我是OSGi的新手。
我正在开发一个插件A(osgi包),假设依赖于库的 A ,假设 B-1.0 和 C-1.0 。现在如果库 C-1.0 依赖于库 B-2.0 (注意:不同版本的库 B )。所以我的插件在其类路径中有两个不同版本的库 B 。现在,我该如何处理这种情况?
由于我在过去4-5天内研究过OSGi,它为JIRA应用程序中的每个插件创建了一个类加载器,因此插件之间不会出现依赖版本不匹配。但是开发人员会做什么?如果插件本身需要两个不同版本的库jar?
我可以通过OSGi在单个osgi包中创建两个不同的类加载器,比如一个用于包X,另一个用于包Y吗?
请帮助我完成上述任何一种情况,或指出我正确的方向。
提前致谢。
答案 0 :(得分:1)
请记住捆绑包不依赖于其他捆绑包 !!
其他捆绑包导出的导出包。 (除非你使用过Require-Bundle
,否则你不应该)。所以从你的例子中重新描述场景:
捆绑 A 导入包org.foo
。捆绑 C 导出包org.foo
,OSGi将导入连接到导出。到目前为止一切顺利。
捆绑 C 还会导入包org.bar
。捆绑 B 1.0 导出包org.bar
。因此,OSGi将这些连接在一起,一切都很好。
现在......捆绑 A 还会导入包org.wibble
。捆绑 B 2.0 导出包org.wibble
。这也很好!就OSGi而言,捆绑 B 1.0 和 B 2.0 只是不同的捆绑包,它们都可以同时安装。
因此,当您按照实际工作方式查看依赖关系时,您会发现 A 完全可以导入来自两个不同版本的 B 的代码。但是有一个限制。请考虑以下事项:
org.foo
和org.bar v1.0
(是的,包已版本化)。org.foo
,以满足 D 中的导入。捆绑 E 还会导入包org.bar v2.0
。org.bar
个包的2个版本。实际上这种情况仍然有效。 D 可以从某个地方导入包org.bar
的1.0版本, E 可以从其他地方同时导入包org.bar
的2.0版},同时正如 D 从 E 导入包org.foo
。我个人认为这非常不可思议!但如果org.foo
“使用”org.bar
,则无效,其中“使用”表示org.bar
中的某些类型在org.foo
的API中可见。在这种情况下,捆绑 D 会暴露给2个不同的副本org.bar
,这是不允许的,因此OSGi会阻止捆绑 D 运行,因为不允许它进入RESOLVED或ACTIVE状态。
答案 1 :(得分:0)
在osgi包或插件中你将拥有meta-inf flie,它将定义你导入哪些类,如果你传递额外的agrument版本= 2.0,那么如果你没有指定任何东西它将使用B-2.0中的类然后它将解析为首先由classloader加载的那个。
即。 import-package(C 1.0): b.some.package; version =“2.0”或b.some.package;版本= “[2.0,4.0)”
import-package(A 1.0): b.some.package; version =“1.0”或b.some.package;版本= “1.0”
希望这有帮助
阿努普
答案 2 :(得分:0)
由于每个OSGi包都有自己的类加载器,运行时将有4个包,还有4个类加载器(A,B-1.0,B-2.0,C-1.0)。
B中可能包含两个相同类的副本(一个来自1.0,另一个来自2.0)。如果你运行它,你可能只是在A代码中遇到ClassCastException,因为两个版本的B类不一样。
OSGi提供"使用"条款提前检测这种情况。例如,C可能有如下的uses子句:
Export-Package: c.some.package;uses="b.some.package";version="1.0"
Import-Package: b.some.package;version="2.0"
在这种情况下,您将遇到早期失败(在解析A时),称为使用冲突,因为C会将其使用者的约束放在可接受的B版本上。
从概念上讲,解决此问题的唯一方法是让B的消费者(在这种情况下为A和C)同意B的版本。