导入的片段包是否包含在主机包类路径中?

时间:2013-09-09 08:03:44

标签: java osgi

我对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来修改bundle Foo的类路径吗?或者这种依赖只适用于片段中的类吗?

长话短说: OSGi中Class.forName()的语义是什么,当在Host bundle的类中执行时?它包括:

  • 问:捆绑类? A:是的。
  • 问:片段中包含的类?答:是的。 Source
  • 问:导入的软件包和从必需软件包导出的软件包? A:是的。
  • 问:导入的包和从所有片段的必需包中导出的包?答:我不知道。

1 个答案:

答案 0 :(得分:4)

参见OSGi Core规范5.04版的第3.14节。

摘要:您可以添加仅包含Import-Package标头或Require-Bundle标头的片段。这些标头中的子句将附加到主机包中的相应标头中。所以如果你添加:

 Fragment-Host:  Foo;version="[1,2)"
 Import-Package: org.myPackage;version="[1,2)"

然后Foo包就能看到你的MyClass。

请注意summarizeClass中的代码假设存在单个类空间,并且类名称唯一地标识特定类。但是,大型应用程序具有依赖树,这些依赖树经常使用相同依赖项的冲突版本。对于这些情况,这种假设因此是非常错误的。 OSGi保证任何类在解析时都能看到一致的类空间,尽管不同的bundle可以看到不同的类空间。此功能要求OSGi知道您的捆绑包需要哪些包。可悲的是,Class.forName还有其他不良品质(它在内存中引入类)并且几乎总是非常不必要。