从实现包中导出API

时间:2014-04-29 15:28:06

标签: osgi bnd

有人可以向我解释BND导出捆绑包没有的api包背后的理由。这对我来说似乎是错的,它总是(AFAICT)导致 ClassNotFoundException

Especifically
捆绑包A包含com.foo.api.MyInterface
bundle B包含实现com.foo.impl.InterfaceImpl

MyInterface

因此,如果我告诉bnd在包A中导出包com.foo,他将正确导出com.foo.api,但如果我告诉包B中的导出包com.foo,它将错误地导出{{1因此, MyInterface 的使用者将连接到bundle B,然后在运行时获得ClassNotFoundException

为什么BND不保证当捆绑包导出一个实际包含它的包???

我知道如果我导出com.foo.apicom.foo.api而不是com.foo.impl,那么问题就会在我的简单示例中得到解决,但在我们的实际系统中,这并不是真正的可行性。此外,实际的问题是为什么BND这样做,而不是如何解决问题。我已经知道解决问题的解决方法

3 个答案:

答案 0 :(得分:1)

这只是bnd语法的一个特性。因为bnd可以选择嵌入导入的包,所以在确定Export-Package和Private-Package标头时会考虑整个类路径。 Bnd并没有对正在处理的文件夹和其他类似路径上的其他类进行区分。

因此,如果您的Export-Package语句包含bnd知道的包,则bnd将假设您要嵌入并导出它们。不过,我很惊讶你看到异常,因为bnd也应该在打包的包中物理地包含导出的类。

答案 1 :(得分:1)

你是否看到B组看到com.foo.api不在那里?如果告诉bnd bundle B应该导出com.foo.api,那么bnd实际上会将该包放入bundle B然后导出它。 bnd具有“权力”,可以在生成的包中的-buildpath中的任何位置包含类。我认为你真的不希望bundle B包含并导出com.foo.api,所以你应该修改你的bnd文件以删除export语句。

答案 2 :(得分:0)

我还没有直接使用bnd,而是通过maven bundle插件,它应该非常相似。我发现如果你导出一个你没有的包,那么bnd会将这个包的类嵌入你的包中。

因此,至少在使用maven bundle插件时,B应该在定义com.foo.api的导出时嵌入接口。不确定当你只将父包定义为导出时会发生什么,但我会假设同样的情况发生。

如果你想将api与每个bundle一起部署,我不经常这样做,但这似乎是OSGi中的一种最佳实践(例如对于实现OSGi apis的bundle),这种自动嵌入非常有用。