我已经尝试了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的,但它们具有类似的概念。


当前回答

java.lang.NoClassDefFoundError

指示在编译时找到了一些东西,但在运行时没有找到。也许你只需要把它添加到类路径中。

其他回答

如果您正在使用Maven,这可能是由于pom.xml中依赖关系的范围(如果它们被设置为“提供”),请尝试将其更改为“编译”。

在我的环境中,我在单元测试中遇到了这个问题。在将一个库依赖项附加到*之后。砰,这是固定的。

例子:

错误信息:

java.lang.NoClassDefFoundError: com/abc/def/foo/xyz/Iottt

POM内容:

<dependency>
    <groupId>com.abc.def</groupId>
    <artifactId>foo</artifactId>
    <scope>test</scope>
</dependency>

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

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

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

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

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

我的观点是:

确保类路径包含完整路径(/home/user/lib/some_lib.jar而不是~/lib/some_lib.jar),否则仍然会面临NoClassDefFoundError错误。

如果您从JAR文件“开始”一个类,请确保从JAR完整路径开始。例如,(如果你的“主类”没有在Manifest中指定):

java -classpath "./dialer.jar" com.company.dialer.DialerServer

如果存在任何依赖关系,例如对其他JAR文件的依赖关系,则可以解决此类依赖关系

或者通过将这样的JAR文件(每个JAR文件的完整路径)添加到类路径。例如,

java -classpath "./libs/phone.jar;./libs/anotherlib.jar;./dialer.jar" com.company.dialer.DialerServer

或者通过向清单中添加“依赖JAR无文件”来编辑JAR清单。这样的清单文件可能如下所示:

Manifest-Version: 1.0
Class-Path: phone.jar anotherlib.jar
Build-Jdk-Spec: 1.8
Main-Class: com.company.dialer.DialerServer

或者(如果你是一个有源代码的开发人员),你可以使用Maven为你准备一个清单,添加到*。pom文件:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
                <mainClass>com.company.dialer.DialerServer</mainClass>
                <!-- Workaround for Maven bug #MJAR-156 (https://jira.codehaus.org/browse/MJAR-156) -->
                <useUniqueVersions>false</useUniqueVersions>
            </manifest>
        </archive>
    </configuration>
</plugin>

请注意,上面的例子使用;作为类路径中的分隔符(它对Windows平台有效)。在Linux上,替换;:。

例如,

java -classpath ./libs/phone.jar:./libs/anotherlib.jar:./dialer.jar
com.company.dialer.DialerServer