Apache Felix文件从deploy文件夹安装jar

时间:2015-09-03 23:01:48

标签: apache maven osgi apache-felix osgi-bundle

我正在尝试将Apache Felix File Install与嵌入版本的Felix一起使用。基本思路很简单,我有一个可以使用标准java -jar app.jar启动的jar应用程序文件,应用程序将启动Apache Felix框架,然后查看hot deploy文件夹,安装,更新和删除OSGi包在运行时从该文件夹中放置/更新/删除。

我目前已设法创建启动嵌入式Felix的功能,如果我通过BundleContext.installBundle()指定它们,我可以部署捆绑包但我无法从热文件夹中动态收集jar捆绑包

这就是我目前所拥有的:

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();
}

2 个答案:

答案 0 :(得分:1)

事实证明felix.fileinstall本身是一个必须在主机应用程序中启动才能看到目录的包。从我的初始实现到工作所需的只是安装并启动fileinstall包:

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

答案 1 :(得分:0)

您需要使用Felix AutoProcessor并将属性传递给它以及框架。

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");

然后实例化框架并运行AutoProcessor,如下所示:

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然后调用AutoProcessor.processAutoDeploy,它会在启动时自动部署捆绑包。 如果不打电话AutoProcessor.process,它就会失败,这可能是你的问题。