我已经尝试了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);
    }
}

我哪里做错了?

更新

在我把Main类放入图形包之后(我添加了图形包;对于它),将类路径设置为“_test”(包含图形的文件夹),编译它,并使用Java图形运行它。Main(从命令行),它工作正常。

真的很晚更新#2

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


当前回答

我正在开发一个基于Eclipse的应用程序,也称为RCP(富客户端平台)。 在重构(将一个类从一个plugIn移动到一个新的plugIn)之后,我一直面临着这个问题。

清理项目和Maven更新没有帮助。

这个问题是由Bundle-Activator没有自动更新引起的。手动更新MANIFEST下的捆绑激活器。MF在新的插件已经解决了我的问题。

其他回答

我想纠正其他人对NoClassDefFoundError的看法。

NoClassDefFoundError的发生有多种原因,比如:

没有为该引用的类找到.class,无论它在编译时是否可用(i. ClassNotFoundException)。E基类/子类)。 类文件已定位,但在初始化静态变量时引发异常 类文件定位,在初始化静态块时引发异常

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

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

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

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

编译时类和运行时类是不同的,例如,基类是使用子类的类名加载的 forname(“名称”) 例如:两个类,A和B(扩展A) A A = Class.forName("B").newInstance();

在编译代码之后,程序中的每个类都有.class文件。这些二进制文件是Java解释以执行程序的字节码。NoClassDefFoundError表示负责动态加载类的类加载器(在本例中为java.net.URLClassLoader)无法为您试图使用的类找到.class文件。

Your code wouldn't compile if the required classes weren't present (unless classes are loaded with reflection), so usually this exception means that your classpath doesn't include the required classes. Remember that the classloader (specifically java.net.URLClassLoader) will look for classes in package a.b.c in folder a/b/c/ in each entry in your classpath. NoClassDefFoundError can also indicate that you're missing a transitive dependency of a .jar file that you've compiled against and you're trying to use.

例如,如果你有一个类com.example。Foo,编译后你会有一个类文件Foo。class。例如,您的工作目录是…/project/。那个类文件必须放在…/project/com/example,然后将类路径设置为…/project/。

旁注:我建议充分利用Java和JVM语言的惊人工具。像Eclipse和IntelliJ IDEA这样的现代ide和像Maven或Gradle这样的构建管理工具将帮助您不必担心类路径,而将注意力集中在代码上!也就是说,这个链接解释了在命令行上执行时如何设置类路径。

此异常的错误来源之一可能源于Proguard的不一致定义,例如缺少

-libraryJars “path.to.a.missing.jar.library”。

这就解释了为什么在JAR文件存在的情况下,编译和运行工作正常,而清理和构建则失败。记住要在ProGuard设置中定义新添加的JAR库!

请注意,来自ProGuard的错误消息确实不符合标准,因为它们很容易与JAR文件根本不存在时到达的类似Ant消息混淆。只有在最底部才会有ProGuard遇到麻烦的小提示。因此,开始搜索传统的类路径错误等是非常合乎逻辑的,但这将是徒劳的。

显然,NoClassDefFound异常将是运行时的结果,例如,基于缺乏ProGuard一致性构建的可执行JAR文件。有人称之为ProGuard“地狱”。

在一个NetBeans项目上工作了好几个月之后,在收到“低内存”警报后不久,我突然收到了NoClassDefFoundError消息。进行Clean重建并没有帮助,但是完全关闭NetBeans并重新启动项目时没有出现错误报告。

我在Android Studio中也遇到过这种情况。

对我来说有效的解决方案是:重启Android Studio。