运行包含库 jar 的 jar 时出现 Java NoClassDefFoundError [英] Java NoClassDefFoundError when running jar containing library jar

查看:41
本文介绍了运行包含库 jar 的 jar 时出现 Java NoClassDefFoundError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

几个小时后,即使在阅读了大量文档和 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆