为什么Java中会出现NoClassDefFoundError?

为什么Java中会出现NoClassDefFoundError?,java,noclassdeffounderror,Java,Noclassdeffounderror,当我运行Java应用程序时,我得到一个NoClassDefFoundError。这通常是什么原因造成的?这是由于存在代码所依赖的类文件,并且该类文件在编译时存在,但在运行时找不到。查找构建时和运行时类路径中的差异 这是由于存在代码所依赖的类文件,并且该类文件在编译时存在,但在运行时找不到。查找构建时和运行时类路径中的差异 我发现,当使用运行时发现的类的不兼容版本编译代码时,有时会出现NoClassDefFound错误。我记得的具体实例是ApacheAxis库。实际上,我的运行时类路径上有两个版本

当我运行Java应用程序时,我得到一个
NoClassDefFoundError
。这通常是什么原因造成的?

这是由于存在代码所依赖的类文件,并且该类文件在编译时存在,但在运行时找不到。查找构建时和运行时类路径中的差异

这是由于存在代码所依赖的类文件,并且该类文件在编译时存在,但在运行时找不到。查找构建时和运行时类路径中的差异

我发现,当使用运行时发现的类的不兼容版本编译代码时,有时会出现NoClassDefFound错误。我记得的具体实例是ApacheAxis库。实际上,我的运行时类路径上有两个版本,它拾取的是过期且不兼容的版本,而不是正确的版本,导致NoClassDefFound错误。这是在一个命令行应用程序中,我使用了与此类似的命令

set classpath=%classpath%;axis.jar
我能够通过使用以下工具使其获得正确的版本:

set classpath=axis.jar;%classpath%;

我发现,当使用运行时发现的类的不兼容版本编译代码时,有时会出现NoClassDefFound错误。我记得的具体实例是ApacheAxis库。实际上,我的运行时类路径上有两个版本,它拾取的是过期且不兼容的版本,而不是正确的版本,导致NoClassDefFound错误。这是在一个命令行应用程序中,我使用了与此类似的命令

set classpath=%classpath%;axis.jar
我能够通过使用以下工具使其获得正确的版本:

set classpath=axis.jar;%classpath%;

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

在这种情况下,在我们的头脑中保持两个或三个不同的例外是很重要的:

  • java.lang.ClassNotFoundException
    此异常表示在类路径上找不到该类。这表明我们试图加载类定义,而类路径上不存在该类

  • java.lang.NoClassDefFoundError
    此异常表示JVM在其内部类定义数据结构中查找类的定义,但未找到。这不同于说它不能从类路径加载。通常这表示我们以前试图从类路径加载一个类,但由于某种原因失败了-现在我们尝试再次使用该类(因此需要加载它,因为它上次失败了),但我们甚至不打算尝试加载它,因为我们之前加载它失败了(并且有理由怀疑我们会再次失败)。早期的故障可能是ClassNotFoundException或ExceptionInInitializeError(指示静态初始化块中的故障)或任何数量的其他问题。关键是,NoClassDefFoundError不一定是类路径问题


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

    在这种情况下,在我们的头脑中保持两个或三个不同的例外是很重要的:

  • java.lang.ClassNotFoundException
    此异常表示在类路径上找不到该类。这表明我们试图加载类定义,而类路径上不存在该类

  • java.lang.NoClassDefFoundError
    此异常表示JVM在其内部类定义数据结构中查找类的定义,但未找到。这不同于说它不能从类路径加载。通常这表示我们以前试图从类路径加载一个类,但由于某种原因失败了-现在我们尝试再次使用该类(因此需要加载它,因为它上次失败了),但我们甚至不打算尝试加载它,因为我们之前加载它失败了(并且有理由怀疑我们会再次失败)。早期的故障可能是ClassNotFoundException或ExceptionInInitializeError(指示静态初始化块中的故障)或任何数量的其他问题。关键是,NoClassDefFoundError不一定是类路径问题


  • 下面是说明
    java.lang.NoClassDefFoundError
    的代码。详细解释请参见

    NoClassDefFoundErrorDemo.java

    SimpleCalculator.java


    下面是说明
    java.lang.NoClassDefFoundError
    的代码。详细解释请参见

    NoClassDefFoundErrorDemo.java

    SimpleCalculator.java

    我正在使用,并在我的项目中解决了这个错误

    类中存在运行时错误。我将属性读取为整数,但当它从属性文件中读取值时,其值是双倍的

    Spring没有给出运行时失败的行的完整堆栈跟踪。 它只是说
    NoClassDefFoundError
    。但当我将其作为本地Java应用程序执行时(将其从MVC中删除),它给出了
    异常InInitializeRerror
    ,这是真正的原因,也是我跟踪错误的方式

    @xli的回答让我洞察了代码中可能存在的错误。

    我使用了,并在我的项目中解决了这个错误

    类中存在运行时错误。我将属性读取为整数,但当它从属性文件中读取值时,其值是双倍的

    Spring没有给出运行时失败的行的完整堆栈跟踪。 它只是说
    NoClassDefFoundError
    。但当我将其作为本地Java应用程序执行时(将其从MVC中删除),它给出了
    异常InInitializeRerror
    ,这是真正的原因,也是我跟踪错误的方式

    @xli的回答给出了答案
    // ClassLoaderTracer.java
    // From: https://blogs.oracle.com/sundararajan/entry/tracing_class_loading_1_5
    
    import java.lang.instrument.*;
    import java.security.*;
    
    // manifest.mf
    // Premain-Class: ClassLoadTracer
    
    // jar -cvfm tracer.jar manifest.mf ClassLoaderTracer.class
    
    // java -javaagent:tracer.jar  [...]
    
    public class ClassLoadTracer 
    {
        public static void premain(String agentArgs, Instrumentation inst) 
        {
            final java.io.PrintStream out = System.out;
            inst.addTransformer(new ClassFileTransformer() {
                public byte[] transform(ClassLoader loader, String className, Class classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) throws IllegalClassFormatException {
    
                    String pd = (null == protectionDomain) ? "null" : protectionDomain.getCodeSource().toString();
                    out.println(className + " loaded by " + loader + " at " + new java.util.Date() + " in " + pd);
    
                    // dump stack trace of the thread loading class 
                    Thread.dumpStack();
    
                    // we just want the original .class bytes to be loaded!
                    // we are not instrumenting it...
                    return null;
                }
            });
        }
    }
    
    android {
        compileSdkVersion 23
        buildToolsVersion '22.0.1'
        packagingOptions {
        }
    
        defaultConfig {
            minSdkVersion 17
            targetSdkVersion 23
            versionCode 11
            versionName "2.1"
        }
    
    private static HttpHost proxy = new HttpHost(proxyHost, Integer.valueOf(proxyPort), "http");
    
    System.out.println(TheNoDefFoundClass.class.getProtectionDomain().getCodeSource().getLocation());
    
    dexOptions {
            preDexLibraries false
            ...
    
    sdk list java
    sdk install java 8u152-zulu
    sdk use java 8u152-zulu
    
    mvn clean install -DskipTests
    
    mvn test
    
    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);
    }
    
    static class Example {
        static {
            thisThrowsRuntimeException();
        }
    }
    
    static class OuterClazz {
    
        OuterClazz() {
            try {
                new Example();
            } catch (Throwable ignored) { //simulating catching RuntimeException from static block
                // DO NOT DO THIS IN PRODUCTION CODE, THIS IS JUST AN EXAMPLE in StackOverflow
            }
    
            new Example(); //this throws NoClassDefFoundError
        }
    }
    
    package valentines;
    
    import java.math.BigInteger;
    import java.util.ArrayList;
    
    public class StudentSolver {
        public static ArrayList<Boolean> solve(ArrayList<ArrayList<BigInteger>> problems) {
            //DOING WORK HERE
            
        }
        public static void main(String[] args){
            //TESTING SOLVE FUNCTION
        }
        
    }
    
    MyClass myClass = new MyClass();
    
    MyClass myClass = (MyClass) Class.forName("MyClass").newInstance();