Apache Felix File Install jar from deploy folder

匿名 (未验证) 提交于 2019-12-03 01:26:01

问题:

I am trying to use Apache Felix File Install with an embedded version of Felix. The basic idea is simple, I have a jar application file that can be launched using standard java -jar app.jar and the application will startup Apache Felix framework and then look in a hot deploy folder installing, updating and removing the OSGi bundles that are in/placed/updated/removed from that folder at runtime.

I currently have managed to create the ability to startup the embedded Felix and I can deploy bundles if I specify them via BundleContext.installBundle() but I cant get the jar bundles to be dynamically harvested from the hot folder.

This is what I currently have:

public static void main(String[] args) throws Exception {      System.setProperty("felix.fileinstall.noInitialDelay", "true");     System.setProperty("felix.fileinstall.poll", "1000");     System.setProperty("felix.fileinstall.dir", "./hot-deploy");      System.out.println("Building OSGi Framework");      FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next();     Map<String, String> config = new HashMap<>();      // make sure the cache is cleaned     config.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);      // more properties available at: http://felix.apache.org/documentation/subprojects/apache-felix-service-component-runtime.html     config.put("ds.showtrace", "true");     config.put("ds.showerrors", "true");      Framework framework = frameworkFactory.newFramework(config);     framework.start();      // declarative services dependency is necessary, otherwise they won't be picked up!     loadScrBundle(framework);      BundleContext context = framework.getBundleContext();     List<Bundle> installedBundles = new LinkedList<>();      //installedBundles.add(context.installBundle("file:./Sandbox/osgiTest/module-a/target/module-a-1.0-SNAPSHOT.jar"));      for (Bundle bundle : installedBundles) {         if (bundle.getHeaders().get(Constants.FRAGMENT_HOST) == null) {             bundle.start();         }     }      try {         framework.waitForStop(0);     } finally {         System.exit(0);     }  }  private static void loadScrBundle(Framework framework) throws URISyntaxException, BundleException {     URL url = Activator.class.getClassLoader().getResource("org/apache/felix/scr/ScrService.class");     if (url == null) {         throw new RuntimeException("Could not find the class org.apache.felix.scr.ScrService");     }     String jarPath = url.toURI().getSchemeSpecificPart().replaceAll("!.*", "");     System.out.println("Found declarative services implementation: " + jarPath);     framework.getBundleContext().installBundle(jarPath).start(); } 

回答1:

Turns out that felix.fileinstall itself is a bundle that must be started in the host application before it can watch a directory. All that is required from my initial implementation to work is to install and start the fileinstall bundle:

installedBundles.add(context.installBundle("file:path/to/fileinstall.jar")); 


回答2:

You need to make use of the Felix AutoProcessor and pass the properties to it as well to the framework.

final Map<String, String> config = new HashMap<>(); // Probably there is a much better way to o this... System.getProperties().forEach((key, value) -> config.put(key.toString(), value.toString()));  // Set the properties config.put(AutoProcessor.AUTO_DEPLOY_DIR_PROPERTY, "hot-deploy"); config.put(AutoProcessor.AUTO_DEPLOY_ACTION_PROPERTY, "install,update,start"); config.put(Constants.FRAMEWORK_STORAGE_CLEAN, Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT); config.put(Constants.FRAMEWORK_STORAGE, "cache"); 

Then instantiate the framework and run the AutoProcessor as followed:

final FrameworkFactory factory = new org.apache.felix.framework.FrameworkFactory(); final Framework framework = factory.newFramework(config);  try {     framework.init();      AutoProcessor.process(config, framework.getBundleContext());      FrameworkEvent event;      do     {         framework.start();         event = framework.waitForStop(0L);      } while (event.getType() == 128);  } catch (final Throwable e) {     e.printStackTrace(); } 

AutoProcessor.process calls AutoProcessor.processAutoDeploy then, which auto deploys the bundles at startup. Without calling AutoProcessor.process it won't work which probably was your issue.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!