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