【问题标题】:Java NoClassDefFoundError when running jar containing library jar运行包含库 jar 的 jar 时出现 Java NoClassDefFoundError
【发布时间】:2012-10-01 06:31:20
【问题描述】:

几个小时后,即使阅读了大量文档和 SO 问题,我也无能为力了。我确定我遗漏了一些明显的东西,但我就是想不通。

我创建了许多 java 文件,包括一个带有 main 方法的入口点。该类还使用了一个“库”类,该类位于 com.test.lib.MyLibraryClass.class 中,位于 jar 文件 mylib.jar 中。我正在使用以下 ant XML 成功构建 my jar 文件。

<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。

但是,当我尝试运行 jar 时,出现以下错误:

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

我需要改变什么?我是否生成了格式错误或不完整的清单?

非常感谢!

【问题讨论】:

    标签: java ant classpath


    【解决方案1】:

    问题是标准类加载器无法找到在另一个 JAR 中的 JAR 中的类。 Class-Path 清单变量实际上告诉 JVM 将当前目录中的 mylib.jar 文件添加到类路径中。

    有三种解决方案:

    • mylib.jar 文件放在可以找到的位置(并相应地设置清单属性。

    • 创建一个 Uber-jar,将主 JAR 中的类和所有相关库 JAR 合并到一个 JAR 文件中。

    • 编写一个时髦的类加载器,它知道如何从 JAR-in-a-JAR 加载,并修改应用程序以实例化和使用类加载器。 (不推荐这种方法...)

    请注意,前两个替代方案通过摆脱 JAR-in-a-JAR 结构来解决问题......以不同的方式。

    【讨论】:

    • @Walker 在执行 jar 时可以使用 java -cp jarfile jartoexecute 它应该可以正常工作。
    • @Stranger - 但这并不能直接解决 JAR 问题中的 JAR。
    【解决方案2】:

    如果您尝试使用java 命令运行它,则不支持在 jar 中嵌入 jar。使用清单中的该条目,类加载器将在您启动类的基本文件夹中查找 jar,而不是在 Jar 中。您可以将mylib.jar 放在基本文件夹中并使用-cp mylib.jar 选项运行java,或者使用任何支持运行带有嵌入式jar 的jar 的工具。看看this 或只是 Google 'jars inside jar',你会得到大量的点击。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-11-28
      • 1970-01-01
      • 2013-04-26
      • 1970-01-01
      • 2011-02-24
      • 2023-04-08
      • 2012-12-01
      • 2015-04-01
      相关资源
      最近更新 更多