OSGi:如何确保类路径一致性?

时间:2011-09-19 17:57:39

标签: osgi noclassdeffounderror classnotfoundexception

根据OSGi文档,OSGi旨在帮助防止ClassPath问题。

例如,来自“OSGi in action”:

  

启动应用程序时ClassNotFoundExceptions因为   类路径不正确。 OSGi可以通过确保代码来提供帮助   在允许代码执行之前满足依赖性。

然而,由于我们已经将我们的java应用程序切换到OSGi,我看到了比以往更多的ClassNotFoundExceptions,尤其是NoClassDefFoundErrors。 OSGI类加载器不再能够找到以前加载正常的类,更糟糕的是:在运行时遇到错误,这意味着除非通过手动测试应用程序的每个角落,否则无法轻松检查它。

例如,我们的应用程序在OSGi下运行愉快,但我们收到了Beta测试人员的报告,他们无法再将文档导出为PDF。实际上,当我查看它时,我发现此功能导致异常被记录:

java.lang.NoClassDefFoundError: org/w3c/dom/Node

那么,OSGi实际上是否创造了比它解决的更多的类路径问题?

更重要的是:我如何测试我的类路径是否一致,所有必需的Import-Package语句等。之前我在错误报告中读到了它们?

3 个答案:

答案 0 :(得分:13)

OSGi应用程序不会抛出ClassNotFoundExceptions和NoClassDefFoundErrors 如果您的清单是正确的。也就是说,您需要告诉OSGi您的捆绑包使用哪些包;如果你没有正确或诚实地做到这一点,那么OSGi无法帮助你。换句话说:GIGO(Garbage In,Garbage Out)。

例如,您使用包org.w3c.dom但未将其列在Import-Package语句中。因此,OSGi不知道您需要访问该软件包,因此当您实际尝试从该软件包加载类时,它们将无法使用。

因此,您需要确保您的Import-Package声明对于捆绑包实际使用的包是准确的。好消息是“bnd”工具可以通过生成包清单来为您完成此操作,使用字节码分析来查找所有静态引用的包。

<强>更新 最后一个问题询问如何在运行时发现问题之前测试捆绑包是否一致。 Bnd有一个“验证”功能,正是这样做的。实际上,如果您首先使用Bnd生成清单,那么您将不需要验证功能。但是,我对您的构建过程一无所知,因此您可能会发现很难在短期内转向基于Bnd的构建......在这种情况下,将验证任务添加为后期相对简单构建后的处理步骤。但是我仍然建议在构建过程中尽早使用Bnd。

答案 1 :(得分:2)

我认为这里的问题是你没有指定捆绑包使用的正确的包/类集(使用MANIFEST中的Import-Packages指令)。除非OSGi知道这些,否则它真的无济于事!

不确定如何构建OSGi包,但是应该查看Maven bundle plugin,它解决了显式指定Import-Packages的问题(至少对于编译时包)。请参阅http://wso2.org/library/tutorials/develop-osgi-bundles-using-maven-bundle-plugin#Importing%20packages

答案 2 :(得分:1)

我没有回答核心问题,而是为类似问题提供解决方案。

就我而言,我有这个类结构:

  • interface javax.script.ScriptEngineFactory
  • class pkga.A implements ScriptEngineFactory
  • class pkgb.B extends A

我的主要项目代码在类B中,并且在依赖的Jar中扩展了类A。使用

<Export-Package>pkgb.*</Export-Package> 

不足,我收到错误抱怨缺少javax.script.ScriptEngineFactory。这很奇怪,因为它是标准JDK 8的一部分,请注意包pkgb 中的代码未明确引用javax.script.*;也许Manifest作家不知道这个界面需要导出?

我发现Export-Package指令的这个补充解决了问题

<Export-Package>pkgb.*,javax.script.*</Export-Package>
相关问题