【问题标题】:Installing two bundles with the same file使用相同的文件安装两个捆绑包
【发布时间】:2014-01-27 11:13:24
【问题描述】:

我正在使用 OSGI 声明式服务。

在我的 java 应用程序中,我启动 Apache Felix,然后安装并启动一些包。

使用相同的文件路径安装了两个包。捆绑包启动后,应该会显示“Hello”消息。

当我安装并启动第一个包时:

Bundle bundle1 = context.installBundle("file:C://Users//bundles//myBundle.jar");
bundle1.start();

这会在控制台中显示“Hello”。

但是,当我安装第二个包时(与第一个包具有相同的文件路径)

Bundle bundle2= context.installBundle("file:C://Users//bundles//myBundle.jar");
bundle2.start();

我没有看到任何输出。这意味着第二个包的安装和/或启动被忽略了。

我需要一种方法来安装和启动两个具有相同文件路径的不同包,当我停止其中一个包时,另一个应该保持活动状态。我怎么可能做到这一点?谢谢。

我正在考虑的用例:假设我有两个用户,并且都想使用相同的功能(捆绑)。如果其中一个决定停止捆绑功能,而另一个想要保留它怎么办?

有没有更好的方法来实现这一点?谢谢。

【问题讨论】:

    标签: osgi bundle apache-felix declarative


    【解决方案1】:

    两次安装之间文件内容是否发生变化?如果没有,那么你不能这样做。本质上,您尝试将包实例化两次,而 OSGi 只允许每个包安装一次。

    实际上你可以同时拥有一个包的多个版本,但是Bundle-SymbolicName和Bundle-Version这对在框架内必须是唯一的。

    将用户功能映射到已安装的包确实不是一个好主意。为什么用户应该关心安装在您的应用程序中的模块?相反,您希望捆绑包中的功能支持多个用户。

    【讨论】:

    • 谢谢尼尔,我现在意识到了。但我需要知道您如何在声明式服务中执行此“捆绑中的多种功能”。任何用代码解释这个想法的文件?像往常一样,我尝试从头开始学习 osgi。搜索 API,然后迷路了。
    • 我认为 Balazs 在 cmets 中为他的答案提供的链接非常好。
    【解决方案2】:

    你可以调用函数

    context.installBundle(location, inputStream)

    并将 InputStream 传递给该函数。在这种情况下,您可以指定两个不同的位置(例如,一个具有某种意义但不是真实位置的位置)。

    您的下一个问题是,如果两个具有相同 SymbolicName 和相同版本的包不能存在两次。

    我无法想象同一个包应该安装两次的用例。这可能是一个错误概念的结果。

    【讨论】:

    • 假设我有两个用户。两者都选择了相同的功能,但后来,一个决定停止该功能。 (这里的功能是捆绑)。这不是用例吗?
    • 取决于特征的含义。我认为一个包包含一个功能的实现。通过多次选择该功能,这意味着捆绑包中的类被实例化了多次。例如。您可以创建基于配置工厂的 DS 组件。如果用户创建了新配置,组件将使用该配置进行实例化。
    • 你说的是组件工厂吗?您能否提供一个示例,希望是一个小代码?
    • 这是 google 在搜索声明式服务时返回的第一件事。我说的是代码。
    • 这个怎么样:github.com/everit-org/osgi-liquibase-component/blob/master/… 这是一个 DataSource 组件,它被实例化的次数与可用的配置一样多。这一个的目的是相似的,但使用不同的工具:github.com/osgi/bundles/blob/master/osgi.jdbc/src/osgi/jdbc/…
    【解决方案3】:

    您需要考虑两件事:捆绑位置必须是唯一的,并且框架必须设置为接受具有相同捆绑符号名称的多个捆绑。你应该使用bundleContext.install(location, inputStream) 安装捆绑包。可能是这样的:

    byte[] byteArray byteArray = IOUtils.toByteArray(new FileInputStream(new File(filePath);
    Bundle bundle = bc.installBundle(jobID, new ByteArrayInputStream(byteArray));
    

    并且要使框架能够接受具有相同包符号名称的多个包,您需要使用以下选项启动框架:

    -Dorg.osgi.framework.bsnversion=multiple
    

    请注意,更新命令仍会尝试从给定位置更新捆绑包,在我的情况下 (jobID) 不是真正的文件路径。这与我的用例无关,所以我从不费心去解决它。

    【讨论】:

    • 您能分享一个完整的实现示例吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-21
    • 1970-01-01
    • 1970-01-01
    • 2013-09-12
    • 2012-12-09
    • 1970-01-01
    相关资源
    最近更新 更多