我对OSGi片段和Class.forName()
有一些问题。下面的示例说明了我的问题。
我有第三方捆绑包Foo
。我无法以任何方式修改Foo
。该捆绑软件包含以下类:
public class Serializer {
public String summarizeClass(String className) {
Class<?> myClass = Class.forName(className);
...
}
}
如果我从捆绑软件
Bar
中为org.myPackage.MyClass
调用此方法,它将失败,因为MyClass
不在捆绑软件Foo
的类路径上。我可以简单地添加一个对
Foo.fragment
有依赖性的片段Bar
来修改捆绑包Foo
的类路径吗?还是这种依赖性仅适用于片段中的类?长话短说:
在Host Bundle的类中执行时,OSGi中
Class.forName()
的语义是什么?是否包括:问:捆绑类?答:可以。
问:片段中包含的类?答:可以。 Source
问:导入的软件包和从所需捆绑软件导出的软件包?答:可以。
问:导入的包和从所有片段的必需捆绑包导出的包?答:不知道。
最佳答案
请参阅OSGi Core规范5.0.0版的3.14节。
摘要:您可以添加仅带有Import-Package标头或Require-Bundle标头的片段。这些标题中的子句将附加到主机包中的相应标题中。因此,如果添加:
Fragment-Host: Foo;version="[1,2)"
Import-Package: org.myPackage;version="[1,2)"
然后,Foo捆绑包将能够看到您的MyClass。
请注意,
summarizeClass
中的代码假定存在单个类空间,并且类名唯一地标识特定的类。但是,大型应用程序具有依赖关系树,它们经常使用相同依赖关系的冲突版本。因此,对于这些情况,此假设是非常错误的。 OSGi保证,尽管不同的包可以看到不同的类空间,但是解析时任何类都可以看到一致的类空间。此功能要求OSGi知道捆绑包需要哪些软件包。可悲的是,Class.forName也具有其他劣质(它将类固定在内存中),并且几乎总是没有必要的。关于java - 导入的片段包是否包含在主机包类路径中?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/18693895/