当我运行Java应用程序时,我得到了一个NoClassDefFoundError。造成这种情况的典型原因是什么?


当前回答

下面是演示java.lang.NoClassDefFoundError的代码。具体的解释请看Jared的回答。

NoClassDefFoundErrorDemo.java

public class NoClassDefFoundErrorDemo {
    public static void main(String[] args) {
        try {
            // The following line would throw ExceptionInInitializerError
            SimpleCalculator calculator1 = new SimpleCalculator();
        } catch (Throwable t) {
            System.out.println(t);
        }
        // The following line would cause NoClassDefFoundError
        SimpleCalculator calculator2 = new SimpleCalculator();
    }

}

SimpleCalculator.java

public class SimpleCalculator {
    static int undefined = 1 / 0;
}

其他回答

当我试图在Tomcat/JBOSS服务器上部署应用程序时,我得到了NoClassDefFoundError。我尝试了不同的依赖关系来解决这个问题,但总是得到相同的错误。标记所有javax。*依赖提供在pom.xml,和战争字面上没有依赖。但这个问题还是不断出现。

最终意识到src/main/webapps/WEB-INF/classes有类文件夹被复制到我的战争,所以不是编译类,这个类被复制,因此没有依赖改变解决问题。

因此要小心,如果任何以前编译的数据被复制,删除类文件夹和新的编译后,它工作!..

每个人都在这里谈论一些Java配置的东西,JVM的问题等,在我的情况下,错误与这些主题完全无关,有一个非常琐碎和容易解决的原因:我在我的控制器(Spring Boot应用程序)的端点有一个错误的注释。

虽然这可能是由于编译时和运行时之间的类路径不匹配造成的,但这并不一定是真的。

在这种情况下,记住两到三个不同的异常是很重要的:

java.lang.ClassNotFoundException This exception indicates that the class was not found on the classpath. This indicates that we were trying to load the class definition, and the class did not exist on the classpath. java.lang.NoClassDefFoundError This exception indicates that the JVM looked in its internal class definition data structure for the definition of a class and did not find it. This is different than saying that it could not be loaded from the classpath. Usually this indicates that we previously attempted to load a class from the classpath, but it failed for some reason - now we're trying to use the class again (and thus need to load it, since it failed last time), but we're not even going to try to load it, because we failed loading it earlier (and reasonably suspect that we would fail again). The earlier failure could be a ClassNotFoundException or an ExceptionInInitializerError (indicating a failure in the static initialization block) or any number of other problems. The point is, a NoClassDefFoundError is not necessarily a classpath problem.

我发现,当使用运行时发现的不兼容的类版本编译代码时,有时会得到NoClassDefFound错误。我记得的具体实例是apache axis库。在我的运行时类路径上实际上有2个版本,它正在挑选过时和不兼容的版本,而不是正确的版本,导致NoClassDefFound错误。这是在一个命令行应用程序中,我正在使用类似的命令。

set classpath=%classpath%;axis.jar

我能够让它拿起正确的版本使用:

set classpath=axis.jar;%classpath%;

当静态初始化器试图加载一个在运行时不可用的资源包时,也会发生NoClassDefFoundError,例如受影响的类试图从META-INF目录加载一个属性文件,但不存在。如果你没有捕获NoClassDefFoundError,有时你将无法看到完整的堆栈跟踪;为了克服这个问题,你可以临时为Throwable使用一个catch子句:

try {
    // Statement(s) that cause(s) the affected class to be loaded
} catch (Throwable t) {
    Logger.getLogger("<logger-name>").info("Loading my class went wrong", t);
}