【问题标题】:How to use two versions of the same JAR in two bundles of OSGi?如何在两个 OSGi 包中使用同一个 JAR 的两个版本?
【发布时间】:2018-04-28 06:41:17
【问题描述】:

我有一个使用 maven 的 OSGi 设置。 父包的 pom.xml 依赖于 JAR A,而 JAR A 又依赖于 JAR B(版本 1)。 父母有 2 个孩子捆绑。子捆绑包 1 使用带有版本 1 的 JAR B。 子捆绑包 2 需要版本 2 的 JAR B。 JAR 不向后兼容。所以我无法将 JAR B 的版本从 1 升级到 2。 我需要在 bundle 1 中使用 JAR 的第 1 版,在 bundle 2 中使用同一 JAR 的第 2 版,并且在类加载中没有任何错误。

现在,我在类加载中遇到一个错误,其中任何一个包由于使用 2 个版本而导致 NoClassDefFound 错误而失败。

如何使用 OSGi 解决这种依赖关系?

【问题讨论】:

  • 到目前为止,您只描述了您的 Maven 设置。在 OSGi 中,这无关紧要,在 OSGi 的运行时,清单包含哪些 Import-Package 和 Export-Package 语句很重要。您可以将此添加到您的问题中吗?另一件事。您如何创建捆绑包的清单?
  • @ChristianSchneider 我没有在两个包的 Import-Package 和 Export-Package 中添加有关 JAR B 的信息。但是,我在 bundle 2 的 Require-Bundle 属性中添加了“bundle 1”。这有什么影响吗?
  • 你不应该使用 Require-Bundle。而是让 bnd 通过 maven-bundle-plugin 或 bnd-maven-plugin 为您编写 Manifest。像 gjoranv 提议的那样嵌入依赖也是可能的。

标签: eclipse maven jar osgi


【解决方案1】:

OSGi 的一个优点(可以说是最重要的一个)是您可以在不同的包中使用同一库的不同版本。在少数出现问题的情况下,您可能会收到“违反加载程序约束”或“ClassCastException”。 Vespa 搜索引擎的 OSGi 故障排除文档显示了一些 examples。如果您的一个包调用另一个包中涉及 JAR B 中的类(作为参数或返回值)的 api,并且这两个包使用不同版本的 B,则会发生这种情况。

在您的情况下,问题在于失败的捆绑包缺少导入包,和/或没有捆绑包导出缺少类的包的所需版本。您可以检查捆绑包的manifest.mf 进行验证。

解决此问题的最简单和最安全的方法是将所需版本的 B 嵌入到您的每个子包中。这样,您的子包将使用他们自己的 B 版本,位于单独的类加载器中。

您没有提及如何打包捆绑包,但如果您使用maven-bundle-plugin,它有一个Embed-Dependency 配置选项。请注意,您还必须使用 Embed-Transitive 指令嵌入 B 的传递依赖项,以确保 B 中使用的所有代码在运行时可用。

如果两个版本的 B 都被打包为 OSGi 包,并且每个版本都以唯一的版本号导出(缺少的类的)包,则另一种解决方案是可能的。 (再次,通过查看 B 的manifest.mf 进行验证)。然后,您可以部署两个 B 包,并让您的每个子包导入正确的版本。

【讨论】:

    猜你喜欢
    • 2012-08-02
    • 2014-03-02
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多