如何解决“java.lang.NoClassDefFoundError”?

我已经尝试了Oracle的Java教程中的两个示例。它们都可以正常编译,但在运行时,都出现了这个错误:

Exception in thread "main" java.lang.NoClassDefFoundError: graphics/shapes/Square
    at Main.main(Main.java:7)
Caused by: java.lang.ClassNotFoundException: graphics.shapes.Square
    at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
    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:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    ... 1 more

我想我可能将文件放在错误的文件夹中。Main.java

下面是目录层次结构:

graphics
├ Main.java
├ shapes
|   ├ Square.java
|   ├ Triangle.java
├ linepoint
|   ├ Line.java
|   ├ Point.java
├ spaceobjects
|   ├ Cube.java
|   ├ RectPrism.java

这里是:Main.java

import graphics.shapes.*;
import graphics.linepoint.*
import graphics.spaceobjects.*;

public class Main {
    public static void main(String args[]) {
        Square s = new Square(2, 3, 15);
        Line l = new Line(1, 5, 2, 3);
        Cube c = new Cube(13, 32, 22);
    }
}

我在这里做错了什么?

更新

将类放入包中(我添加到其中),将类路径设置为“_test”(包含图形的文件夹),对其进行编译并使用(从命令行)运行它之后,它起作用了。Maingraphicspackage graphics;java graphics.Main

真的很晚更新#2

我没有使用Eclipse(只是Notepad ++和JDK),上面的更新解决了我的问题。然而,似乎这些答案中有许多是针对Eclipse和IntelliJ IDEA的,但它们有类似的概念。


答案 1

编译代码后,最终会得到程序中每个类的文件。这些二进制文件是 Java 解释以执行程序的字节码。指示负责动态装入类的类装入器(在本例中为)找不到您尝试使用的类的文件。.classNoClassDefFoundErrorjava.net.URLClassLoader.class

如果所需的类不存在(除非使用反射加载了类),则代码将无法编译,因此通常此异常意味着类路径不包含所需的类。请记住,类装入器(特别是)将在类路径中每个条目的文件夹 a/b/c/ 中的包 a.b.c 中查找类。 还可以指示你缺少已编译并尝试使用的.jar文件的可传递依赖项。java.net.URLClassLoaderNoClassDefFoundError

例如,如果你有一个类,编译后你会有一个类文件。例如,假设您的工作目录是 。该类文件必须放在 中,并且应将类路径设置为 。com.example.FooFoo.class.../project/.../project/com/example.../project/

旁注:我建议利用Java和JVM语言中存在的惊人工具。像Eclipse和IntelliJ IDEA这样的现代IDE和像Maven或Gradle这样的构建管理工具将帮助您不必担心类路径(一样多),并专注于代码!也就是说,此链接说明了在命令行上执行时如何设置类路径。


答案 2

我想纠正其他人的观点。NoClassDefFoundError

NoClassDefFoundError可能由于多种原因而发生,例如:

  1. ClassNotFoundException -- 找不到该被引用类的.class,无论它在编译时是否可用(即基类/子类)。
  2. 找到类文件,但在初始化静态变量时引发异常
  3. 找到类文件,初始化静态块时引发异常

在最初的问题中,这是第一个可以通过将CLASSPATH设置为引用的类JAR文件或其包文件夹来纠正的情况。

说“在编译时可用”是什么意思?

  • 引用的类在代码中使用。
    例如:两个类,A和B(扩展A)。如果 B 在代码中直接引用,则在编译时可用,即A a = new B();

说“编译时不可用”是什么意思?

  • 编译时类和运行时类是不同的,即,例如基类使用子类的类名加载,例如Class.forName(“classname”)例如:两个类,A和B(扩展A)。代码具有
    A a = Class.forName("B").newInstance();

推荐