【发布时间】:2019-12-20 00:39:31
【问题描述】:
我有一个 Eclipse 项目,我使用 Ant 构建将其导出到可运行的 jar,并且我使用 jar-in-jar 加载器将一些 jar 库放入项目 jar 中。这曾经有效,而且我记得,更新到 Java 9 是破坏它的原因。我可能是错的,但我只是使用我的罐子一段时间,直到它停止工作。
在 Eclipse 中运行项目可以正常工作,但是当我使用 jar 并从其中一个库中调用方法时,我得到了 NoClassDefFoundError。不管是哪个库。
java.lang.NoClassDefFoundError: myutils/MyUtils
at packagename.Utils.input(Utils.java:42)
at packagename.Main.main(Main.java:83)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:567)
at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: java.lang.ClassNotFoundException: myutils.MyUtils
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:436)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 7 more
这是 Ant 构建:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project default="create_run_jar" name="Create Runnable Jar for Project ProjectName with Jar-in-Jar Loader">
<!--this file was created by Eclipse Runnable JAR file Export Wizard-->
<!--ANT 1.7 is required-->
<!--define folder properties-->
<property name="dir.buildfile" value="."/>
<property name="dir.workspace" value="${dir.buildfile}/.."/>
<property name="dir.libraries" value="${dir.buildfile}/../../libraries"/>
<property name="dir.projectjars" value="${dir.buildfile}/../../project-jars"/>
<target name="create_run_jar">
<jar destfile="${dir.projectjars}/jarname.jar">
<manifest>
<attribute name="Main-Class" value="org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader"/>
<attribute name="Rsrc-Main-Class" value="packagename.Main"/>
<attribute name="Class-Path" value="."/>
<attribute name="Rsrc-Class-Path" value="./ guava-19.0.jar jsoup-1.9.1.jar myutils.jar"/>
</manifest>
<zipfileset src="jar-in-jar-loader.zip"/>
<fileset dir="${dir.buildfile}/bin"/>
<zipfileset dir="${dir.libraries}" includes="guava-19.0.jar"/>
<zipfileset dir="${dir.libraries}" includes="jsoup-1.9.1.jar"/>
<zipfileset dir="${dir.projectjars}" includes="myutils.jar"/>
</jar>
</target>
</project>
编辑:这是MANIFEST.MF:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.10.5
Created-By: 12.0.2+10 (Oracle Corporation)
Main-Class: org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader
Rsrc-Main-Class: packagename.Main
Rsrc-Class-Path: ./ guava-19.0.jar jsoup-1.9.1.jar myutils.jar
Class-Path: .
【问题讨论】:
-
您可以通过使用例如 WinRar(或任何其他支持 .jar 文件的 zip 程序)打开生成的 jar 文件并检查库是否实际上最终在该 jar 中来进一步调查此问题。找到 jars 会将问题简化为类加载问题,找不到 jars 会将问题简化为 ant 构建问题(在构建的 jar 中着色依赖项)。
-
@Pieter12345 罐子确实在那里。
-
在这种情况下,jar-in-jar-loader 无法正确加载 jar。您正在调用的主类运行此代码以获取对 jar 的引用:github.com/eclipse/eclipse.jdt.ui/blob/master/… 您可以看到它从清单中提取 jar 名称。也许您必须在清单中包含这些 jar 名称?您必须参考 jar-in-jar-loader 的文档才能获得确切的格式。
-
@Pieter12345 好吧,我已将清单添加到 OP。即使我知道如何更改清单以使其工作,我也不知道如何更改 Ant 构建以创建正确的清单。
-
我今天在尝试使用我几年前做的一个项目(Java 8)中的旧 build.xml 时遇到了这个问题。它只是行不通(但过去可以正常工作)。我最终通过在 Eclipse 中重新生成 build.xml 来修复它(通过选中“导出可运行 jar”向导中的“另存为 ANT 脚本”复选框)。您可以比较新旧版本以查看差异(这很重要,因为新版本运行良好)。也许这对你有用。
标签: java ant executable-jar noclassdeffounderror