Java 找出any.jar包的依赖项

Java 找出any.jar包的依赖项,java,osgi,bundles,Java,Osgi,Bundles,我正在使用Eclipse开发OSGi捆绑包。我使用EclipseOSGi运行时配置测试代码 代码在那里工作得很好,但是当我将包导出为JAR并尝试在另一个环境(例如pax runner)中使用它们时,我会在运行时遇到ClassNotFound异常。捆绑包安装良好,没有错误。我在equinox上执行命令:“diag bundle number”,它对每个bundle说:“没有未解决的约束” 我想知道,对于一个给定的.jar包,如果它需要任何外部库(manifest.mf中没有描述),是否有一个工具/

我正在使用Eclipse开发OSGi捆绑包。我使用EclipseOSGi运行时配置测试代码

代码在那里工作得很好,但是当我将包导出为JAR并尝试在另一个环境(例如pax runner)中使用它们时,我会在运行时遇到ClassNotFound异常。捆绑包安装良好,没有错误。我在equinox上执行命令:“diag bundle number”,它对每个bundle说:“没有未解决的约束”


我想知道,对于一个给定的.jar包,如果它需要任何外部库(manifest.mf中没有描述),是否有一个工具/方法需要知道。

我以前做过类似的事情(我通过IKVM将Java交叉编译到.NET,但需要jar之间的依赖关系),我用来创建依赖关系图

JBoss刚刚发布了一个关于依赖关系的极好的开源诊断工具:


其中一个功能是通过内省来分析jar文件,以找到所有缺少的依赖项。

如果在运行时找到
Import-Package
中列出的所有包(以及
中列出的包需要bundle
),您的bundle将得到解决。如果解析后得到
ClassNotFoundException
NoClassDefFoundError
,则表示导入包的内容错误


请看下面的图片。这将对从类编译的字节码执行静态检查,以发现确切的依赖关系,并为您生成
Import-Package
语句。通常,如果您使用Bnd,您永远不会看到ClassNotFound/NoClassDefFound,除非通过名称动态加载类,例如使用
Class.forName()

我已经成功使用SpringSource的Bundler shell工具。这里有使用说明。您给它一个JAR,以及要从该JAR创建的新包的名称和版本。然后,它分析JAR中的类文件,并生成一个模板清单,该清单导入它找到引用的任何包

然后,最困难的部分是确定哪些依赖项是可选的,以及依赖于每个包的哪个版本。您必须阅读网站、发行说明等,图书馆才能了解这一点


如果捆绑包没有实际导入任何包或需要其他捆绑包,您将得到“没有未解决的约束”;就OSGi运行时而言,捆绑包是可用的。但一旦它访问外部类(如您的情况),您就会得到可怕的
ClassNotFoundException

如果您的代码使用MANIFEST.MF中未列出的类,Eclipse插件开发环境(PDE)将给您带来编译错误。运行时的ClassNotFound异常通常是由于错误地将包导入标记为可选导致的-包可以解决,但它们无法工作。根据不同版本的捆绑包或包进行编译也可能导致此类错误。

调用Class.forName()后可能会引发异常。无法预测将动态加载的类。您可以添加堆栈跟踪吗?一个jar可能包含对其他地方定义的类的大量引用。只要它们不在运行时使用,就不能将其视为依赖项。所以检查罐子时要小心。