【问题标题】:Apache Felix File Install jar from deploy folderApache Felix File 从部署文件夹安装 jar
【发布时间】:2015-11-29 22:38:10
【问题描述】:

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

我目前已经设法创建了启动嵌入式 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();
}

【问题讨论】:

  • 我认为主要问题是您没有将系统道具传递给 felix 框架本身,这意味着 felix 将无法获取您的“felix.fileinstall.dir”属性。请参阅github.com/apache/felix/blob/… 了解 felix 启动器本身如何处理系统道具。
  • 我查看了代码并尝试将SYSTEM_PROPERTIES_PROP 设置为指向定义felix.fileinstall.dir 属性的config.cfg 文件的系统属性。但是,我什么也没得到。

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


【解决方案1】:

您需要使用 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,它将无法正常工作,这可能是您的问题。

【讨论】:

  • 这是最接近的。你是绝对正确的,这现在允许我定义部署目录,它实际上在启动时部署了位于目录中的 jar 包。但是,当模块从目录中删除时,它不会在运行时卸载它们,也不会在运行时从目录中安装它们。 (注意,我在操作中添加了uninstall
  • 您上面的代码似乎是在实现bundle auto-deploy 而不是file install
  • 我在启动器gist.github.com/Naios/8f5790bce28fae39de9a 中使用此代码,它会按预期部署和启动捆绑包。您可以通过 3.party 捆绑包处理热部署(可能 apache karaf 中有一些东西)。
【解决方案2】:

原来felix.fileinstall 本身就是一个捆绑包,必须在主机应用程序中启动它才能查看目录。从我的初始实现开始,只需安装并启动 fileinstall 包即可:

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

【讨论】:

  • 嗨@tarka。我正在尝试学习如何从热部署文件夹中自动启动捆绑包,但几乎无法获得有关 felix.fileinstall 的任何教程。你知道一个好的 SSCCE 参考,或者任何好的教程吗?谢谢你。希望你能帮忙。
  • @Program-Me-Rev 教程有点薄!基本上,如果您使用 OQ 中的代码。对原始代码的唯一补充是您需要下载(或编译)fileinstall.jar 并在启动时将该 jar 实际注册为 OSGi 依赖项。基本上使用我回复中的代码,但将路径更改为指向您的fileinstall.jar。这应该让你开始。
猜你喜欢
  • 2013-05-15
  • 2012-04-29
  • 2016-11-21
  • 1970-01-01
  • 2015-10-05
  • 2012-03-10
  • 2011-07-15
  • 1970-01-01
  • 2018-12-05
相关资源
最近更新 更多