运行包含库 jar 的 jar 时出现 Java NoClassDefFoundError [英] Java NoClassDefFoundError when running jar containing library jar
问题描述
几个小时后,即使在阅读了大量文档和 SO 问题之后,我也不知所措.我确定我遗漏了一些明显的东西,但我就是想不通.
After several hours, I'm at my wit's end, even after reading reams of documentation and SO questions. I'm certain that I'm missing something obvious, but I just can't figure it out.
我创建了许多 java 文件,包括一个带有 main 方法的入口点.该类还使用一个库"类,位于 com.test.lib.MyLibraryClass.class 中的 jar 文件 mylib.jar.我正在使用以下 ant XML 成功构建 my jar 文件.
I've created a number of java files, including a single entry point with a main method. That class also makes use of one "library" class, located in com.test.lib.MyLibraryClass.class, within a jar file, mylib.jar. I'm building my jar file successfully using the following ant XML.
<target name="jar" depends="compile">
<jar destfile="${jar.dir}/${jar.name}.jar">
<fileset dir="${classes.dir}" />
<fileset dir="${lib.dir}" />
<manifest>
<attribute name="Main-Class" value="${main-class}" />
<attribute name="Class-Path" value="mylib.jar"/>
</manifest>
</jar>
</target>
当我检查通过执行该目标创建的 jar 时,我看到它确实包含我所有的 .class 文件以及 mylib.jar.
When I inspect the jar created by executing that target, I see that it does contain all of my .class files as well as mylib.jar.
然而,当我尝试运行 jar 时,出现以下错误:
When I try to run the jar however, I get the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: com/test/lib/MyLibraryClass
at com.mytest.MyMain.<init>(Unknown Source)
at com.mytest.MyMain.main(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.test.lib.MyLibraryClass
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 2 more
我需要改变什么?我生成的是格式错误或不完整的清单吗?
What do I need to change? Am I generating a malformed or incomplete manifest?
非常感谢!
推荐答案
问题是标准类加载器无法找到位于另一个 JAR 中的 JAR 中的类.Class-Path
清单变量实际上告诉 JVM 将当前目录中的 mylib.jar
文件添加到类路径中.
The problem is that the standard classloader cannot find classes that are in a JAR that is inside another JAR. The Class-Path
manifest variable is actually telling the JVM to add the mylib.jar
file in the current directory to the classpath.
有三种解决方案:
将
mylib.jar
文件放在可以找到的地方(并相应地设置清单属性.
Put the
mylib.jar
file somewhere that it can be found (and set the manifest property accordingly.
创建一个 Uber-jar,将主 JAR 中的类和所有相关库 JAR 合并到一个 JAR 文件中.
Create an Uber-jar that combines the classes in your main JAR and all of the relevant library JARs into one JAR file.
编写一个时髦的类加载器,它知道如何从 JAR-in-a-JAR 加载,并修改应用程序以实例化和使用类加载器.(不推荐这种方法...)
Write a funky class loader that knows how to load from a JAR-in-a-JAR, and modify the application to instantiate and use the classloader. (This approach is NOT recommended ...)
请注意,前两种选择通过摆脱 JAR-in-a-JAR 结构来解决问题……以不同的方式.
Note that the first two alternatives solve the problem by getting rid of your JAR-in-a-JAR structure ... in different ways.
这篇关于运行包含库 jar 的 jar 时出现 Java NoClassDefFoundError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!