2

我创建了一个 jar 文件,其中包括一些包和一对文件。这个类文件使用了另一个我没有包含在 jar 文件中的包 - 我认为这就是我得到这个异常的原因:

Exception in thread "main" java.lang.NoClassDefFoundError: JigMonitorGUI (wrong name: org/w3c/jigmonitor/JigMonitorGUI)

我该如何解决这个问题?

编辑

整个堆栈跟踪:

Exception in thread "main" java.lang.NoClassDefFoundError: JigMonitorGUI (wrong name:  org/w3c/jigmonitor/JigMonitorGUI)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:480)
4

4 回答 4

6

我怀疑你没有完全正确地创建你的 JAR 文件。您的类文件有一个包,但您似乎试图在与该类的包匹配的目录结构中运行该类。

让我们演示如何重现此错误消息。假设我们有以下类:

package abc.def.ghi;

public class Hello {
    public static void main(String[] args) {
        System.out.println("Hello");
    }
}

请注意,此类在包中abc.def.ghi。假设我们将它保存Hello.java在一个目录中C:\Users\Luke\Java,然后从这个目录编译它:

C:\Users\Luke\Java>javac Hello.java

然后我们使用该文件创建一个 JARHello.class文件:

C:\Users\Luke\Java>jar cf test.jar Hello.class

最后,我们尝试从 JAR 中运行这个类:

C:\Users\Luke\Java>java -cp test.jar Hello
Exception in thread "main" java.lang.NoClassDefFoundError: Hello (wrong name: abc/def/ghi/Hello)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        ...

这是您遇到的错误,但类名不同。

问题是该类Hello没有在与其包匹配的目录结构中编译。JVM 在 JAR 的根目录中找到了该类,因此它期望类文件中的类的完全限定名称为Hello. 但是,类文件中的完全限定名称是abc.def.ghi.Hello,这不是 JVM 所期望的,因此它引发了错误。

如果我们改为Hello.java在 subdirectories 内abc\def\ghi,匹配它的 package abc.def.ghi,事情会好一点:

C:\Users\Luke\Java>javac abc\def\ghi\Hello.java

C:\Users\Luke\Java>jar cf test.jar abc\def\ghi\Hello.class

C:\Users\Luke\Java>java -cp test.jar abc.def.ghi.Hello
Hello

编辑:可以通过直接运行类来重现相同的错误,而无需创建 JAR。关键仍然是您试图从与其层次结构匹配的目录结构之外运行该类。

在这一点上,我Hello.classC:\Users\Luke\JavaC:\Users\Luke\Java\abc\def\ghi

C:\Users\Luke\Java>java Hello
Exception in thread "main" java.lang.NoClassDefFoundError: Hello (wrong name: abc/def/ghi/Hello)
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        ...

C:\Users\Luke\Java>java abc.def.ghi.Hello
Hello
于 2012-07-14T19:26:58.543 回答
1

您必须在运行应用程序时传递丢失的 .class 文件。

java -jar -cp <path_to_missing_jars_here> yourJarName.jar
于 2012-07-14T18:26:58.233 回答
1

与其调用java -cp whatever -jar app.jar您,不如编辑 jar 的清单文件。像这样的东西:

Manifest-Version: 1.0
Main-Class: abc.def.Whatever
Class-Path: jar1.jar jar2.jar jar3.jar

(并且不要忘记清单末尾的空行......)

于 2012-07-14T19:30:48.783 回答
0

缺少的类需要在类路径上。如何做到这一点取决于您希望如何部署/运行您的应用程序。

于 2012-07-14T18:28:26.163 回答