从jar文件运行时出现NoClassDefFoundError错误

4

当我在Windows上运行应用程序时,出现“找不到类定义”的异常(在OS X上运行良好)。JVM抱怨的类是我的类(不需要第三方jar包)。当我解压缩jar文件中的文件时,所有文件都存在,包括JVM抱怨的文件。

使用以下任务创建jar:

<target name="jar" depends="">
<jar destfile="build/app.jar" > 
  <manifest>
    <attribute name="Built-By" value="hamza"/>
    <attribute name="Main-Class" value="com.hamza.driver.ui"/>
<attribute name="Class-Path" value="./"/>
  </manifest>
  <fileset dir="build">
    <include name="**/*.class"/>
<include name="**/*.png"/>
<include name="**/*.xpi"/>
<include name="**/*.html"/>
<exclude name="**/*.jar"/>
  </fileset>
</jar>

我无法确定问题的原因。如果我解压缩jar文件并从我解压缩类所在的目录运行jar文件,则一切正常。因此,我假设所有所需的文件都在jar文件中。

编辑:com.hamza.driver.ui是名为com.hamza.driver的包中的一个类,其中包含main

构建后,我得到一个名为“app.jar”的jar文件,并使用“java -jar app.jar”运行它,在OS X上执行良好,但在Windows上不行。

如果我在单独的目录中解压缩app.jar并运行“java -jar app.jar”,则可以正常运行。

编辑2:异常:

Exception in thread "main" java.lang.NoClassDefFoundError: com/hamza/gui/tr
ansfer/ClipboardTransferHandle
        at com.hamza.driver.ui.main(Unknown Source)
Caused by: java.lang.ClassNotFoundException: com.hamza.gui.transfer.Clipboa
rdTransferHandle
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)
        ... 1 more

ClipboardTransferHandle .class文件存在于jar文件中。

编辑3:剪贴板类的导入:

import java.util.logging.Logger;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.DataFlavor;
import java.awt.Toolkit;
import java.io.IOException;

在调试时,我发现如果我尝试在驱动程序中声明ClipboardTransferHandle作为静态变量,则可以正常工作,但是未声明为静态的每个对象都无法找到。所有主要GUI元素都是静态变量,因此可以构建GUI,但是其他元素不行;创建的所有非静态元素都会导致NoClassDefFound,但是如果我将它们声明为静态以进行测试,则它们可以正常工作。


你可以尝试不使用Class-Path属性,然后检查是否能够重现问题。 - VonC
1
展示确切的调用命令 - 如“java -jar my.jar”。如有可能,请提供相关jar包的链接。 - Thorbjørn Ravn Andersen
com.hamza.gui.transfer.ClipboardTransferHandle类中的导入项是什么? - Vineet Reynolds
4个回答

2

以下是问题发生的情况,

如果JAR文件从“C:\java\apps\appli.jar”加载,并且您的清单文件具有Class-Path:引用“lib/other.jar”,则类加载器将在“C:\java\apps\lib\”中查找“other.jar”。它不会查看JAR文件条目“lib/other.jar”。

解决方案:

  1. 右键单击项目,选择导出。
  2. 选择Java文件夹,在其中选择可运行的JAR文件,而不是JAR文件。
  3. 选择适当的选项,在库处理部分选择第三个选项,即(将所需库复制到生成的JAR旁边的子文件夹中)。
  4. 点击完成,您的JAR将与包含清单文件中提到的JAR的文件夹一起创建在指定位置。
  5. 打开终端,为您的jar提供正确的路径,并使用以下命令运行它 java -jar abc.jar

    现在,由于现在它们存在于包含应用程序JAR的相同文件夹中,因此类加载器将在正确的文件夹中查找所引用的JARS..现在没有抛出“java.lang.NoClassDefFoundError”异常。

    这对我有用...希望对你也有用!!!


1
哪个类缺失了?你的Main-Class属性看起来有点可疑——com.hamza.driver.ui是一个类还是一个包?

1

有时候会出现 NoClassDefFoundError 错误(我真的很讨厌这个错误——总是让我发疯……),并不是因为它找不到所告诉你的类(-> 你的类),而是因为 Java 找不到用于实例化该类的某个类之一。

我曾经遇到过这个问题,当一个类从不同的 jar(在我的情况下是 OSGi bundle)中导入另一个类时,后者没有被正确地导出。虽然这是一个 OSGi 特定的问题,但您可能在您的环境中遇到相同的问题。也许您的应用程序依赖于一些在您当前的 OS-X 环境中存在但在当前的 Windows 环境中不存在的类。我不是在看第三方库,而是在看 Java 实现本身。

祝你好运!

编辑

在 SO 上还有两个非常相似的问题,不幸的是没有被接受的解决方案,但也许那里的提示之一可以帮助您解决问题:

运行 jar 文件时出现 NoClassDefFound

jar 文件内部出现 NoClassDefFoundError

编辑 2

这里有一个类似的问题,已经有了一个被接受的答案。希望这个能够帮到你:

尝试使用java.exe -jar运行我的jar文件时出现NoClassDefFoundError错误...是什么问题?


但如果是这样的话,当我解压缩它时它不应该起作用。但它却可以工作。 - Hamza Yerlikaya
只是想让你知道,7年后,你让我免受了更多的挫败感,谢谢! - aRk

0

你是否在classpath中指定了新的jar文件(java -cp .;new.jar MainClass.class)?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接