【问题标题】:How to include Apache Felix to Maven project so that to install bundles programmatically?如何将 Apache Felix 包含到 Maven 项目中以便以编程方式安装包?
【发布时间】:2018-09-13 15:18:03
【问题描述】:

我是 OSGi 和 Apache Felix 的新手。目前我正在通过Maven开发一个桌面应用程序,我想通过插件开发一个应用程序。

考虑一下 Intellij Idea IDE,我正在开发这种 GUI 应用程序。现成的产品将是裸机,即它将具有菜单栏、工具栏、状态栏。但是我想通过 FileChooser 选择 jar 文件来将其他一些组件添加到应用程序中。选择文件后,应用程序将自行安装。例如我想通过外部 jar 文件添加一些新功能,例如新工具按钮或功能等。

而且 OSGi 似乎是非常好的和合适的框架来实现这个特性。 但在几乎所有 OSGi 书籍中,仅通过命令行使用 Apache Felix、Equinox 等工具(框架)安装新包。

我已经创建了 Github 存储库https://github.com/Valeme/osgi-shape-app。 这是 Maven 项目,它有两个模块。第一个是用 JavaFX 编写的 GUI 应用程序(osgi-shape 模块),第二个是插件,安装后应该在 osgi-shape-app 的内容中绘制一些形状。

这是菜单项示例。

MenuItem loadExt = new MenuItem("Load extension");
loadExt.setOnAction(event -> {
    FileChooser fileChooser = new FileChooser();
    fileChooser.setTitle("Open Bundle ");
    fileChooser.getExtensionFilters().addAll(
            new FileChooser.ExtensionFilter("jar", "*.jar"));
    File selectedFile = fileChooser.showOpenDialog(stage);

    System.out.println("selectedFile = " + selectedFile);

    /*
    Here I want to install jar file.
     */
});

插件(bundle jar)将实现Component 接口。这是一个椭圆示例。

public class MyEllipse extends Ellipse implements Component {

    public MyEllipse() {
        super(300, 300, 60, 80);
        setFill(Color.RED);
    }

    @Override
    public Shape getComponent() {

        return this;
    }
}

我已将 Apache Felix 作为依赖项包含在 pom.xml 文件中,现在我想以编程方式安装选定的包(jar 文件)。我被困在这里了。

如何做到这一点?

【问题讨论】:

  • 您希望何时以编程方式安装捆绑软件以及出于什么目的?例如:在编译期间部署到某些测试环境,部署到开发/测试服务器。如果您能多了解一些您想要实现的工作流程,那就太好了。
  • 我想在其中部署我的应用程序,其中包含 OSGi,以便将来我可以通过选择 jar 文件来安装新插件。
  • 这就是我的理解。你提到了Maven。因此,您想使用 maven 部署到实时服务器或测试服务器,或者创建一个包含所有插件的环境的 ZIP,您可以将其复制到某个地方?
  • 我正在开发 GUI 应用程序,而不是服务器一。我已经更新了我的问题,请检查一下。

标签: java maven osgi apache-felix


【解决方案1】:

如果我理解得很好,在您的应用中您需要一个菜单​​项,该菜单项会打开一个文件对话框,您可以在其中选择以编程方式安装的 jar 文件。

您可以使用 BundleContext 以编程方式在 OSGi 中安装任何包。请参阅以下函数:

上面的函数返回一个 Bundle 实例。安装捆绑包后,您至少要激活捆绑包,以便它可以注册其 OSGi 服务。你可以通过调用bundle.start()函数来实现。

还有更复杂的用例,您应该在其中刷新框架的包,但我认为在您的情况下(运行时可安装插件),您几乎不希望拥有其他插件或应用程序本身想要连接的插件.

您可能希望阻止用户获取任何 JAR 文件。为了有一个限制,我会在你的情况下引入一个自定义的 Bundle-Capability。如果一个人想要实现一个插件,他/她必须在他的包中添加一个 Provide-Capability MANIFEST 标头。例如:

Provide-Capability: myappplugin;myappplugin=zipcompressor

在安装 bundle 之前,您可以使用纯 Java API 读取 JAR 文件的 MANIFEST 文件,并使用 bndlibfelix-utils 处理它,这样您就可以获取 JAR-Bundle 是否具有必要功能的信息如果没有则通知用户。

稍后您将希望在该功能中引入新属性,例如:插件想要使用的必要应用程序版本范围。

如果您熟悉 OSGi,这需要几天时间。

【讨论】:

  • 我还有一个问题,我从哪里获得 BundleContext?我想我需要某种框架来实现这个接口,对吧?
  • 我已经更新了我的问题,包括 GitHub 存储库。
  • 如果你启动一个嵌入式框架,你将拥有一个框架实例。 Framework 是 Bundle 接口的子接口,因为 Framework 本身就是系统捆绑包。 Bundle 有一个 getBundleContext 函数。简而言之:Framework.getBundleContext() 如果您可以访问框架。
猜你喜欢
  • 2013-02-17
  • 2020-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-03
  • 2020-11-17
  • 2011-08-11
相关资源
最近更新 更多