原文

对于OSGi的新用户有一个非常普遍的如下问题

我的Bundle抛出一个 NoClassDefFoundError 在 org.example.FooBar, 尽管FooBar是在classpath里,这是啥情况??

OSGi,说有什么东西在classpath甚至是没有什么意义的,因为在OSGi中没有全局的classpath.相反,每一个bundle都有它自己独立的class loader.在每个bundle的class loader里只能加载也在budle里面的classes, 或者显式地从其他bundle导入的classes.

从其他bundle导入classes的更好方式是使用Import-Package. 你必须导入你bundle要使用的每一个包, 除了那些已经是你的bundle的一部分的以java.开头的包(例如java.net, java.util等等, 这些包是由JRE特别处理的.

听起来好像要做很多工作, 但不要担心. 许多开发者使用Bnd来构建他们的bundles, 或者基于类似BndtoolsMaven Bundle Plugin这些工具. 所有这些工具通过检查你的class文件的依赖来自动为你的bundle生成Import-Package元信息.

注意, 你的bundle导入的包, 必须是其他已经安装到OSGi框架的bundle并且使用Export-Package导出同样的包的元信息.在运行时, 框架会检测每一个import以及相应的export的指令是否正确.如果它不能找到一个匹配的export,那么你的bundle将解析(resolve)失败.这发生在一个bundle的生命周期的早期, 并且是在任何代码加载之前发生. 所以, 只要你正确地import了的话, 你不应该会遇到ClassNotFoundException或者NoClassDefFoundError.