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