如何在两个OSGi包中使用同一个JAR的两个版本?

时间:2017-11-15 06:19:48

标签: eclipse maven jar osgi

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

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

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

1 个答案:

答案 0 :(得分:0)

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

在您的情况下,问题是失败的bundle缺少Import-Package,和/或没有bundle使用缺少的类导出所需的包版本。您可以检查要验证的包manifest.mf

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

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

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