[翻译]为什么我的Bundle抛出ClassNotFoundException或者NoClassDefFoundError?
Contents
对于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, 或者基于类似Bndtools
和Maven Bundle Plugin
这些工具. 所有这些工具通过检查你的class文件的依赖来自动为你的bundle生成Import-Package
元信息.
注意, 你的bundle导入的包, 必须是其他已经安装到OSGi框架的bundle并且使用Export-Package
导出同样的包的元信息.在运行时, 框架会检测每一个import
以及相应的export
的指令是否正确.如果它不能找到一个匹配的export
,那么你的bundle将解析(resolve)失败.这发生在一个bundle的生命周期的早期, 并且是在任何代码加载之前发生. 所以, 只要你正确地import
了的话, 你不应该会遇到ClassNotFoundException
或者NoClassDefFoundError
.