当前位置:  开发笔记 > 编程语言 > 正文

为什么我在Java中获得NoClassDefFoundError?

如何解决《为什么我在Java中获得NoClassDefFoundError?》经验,为你挑选了9个好方法。

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



1> Jared..:

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

在这种情况下,重要的是要保持两到三个不同的例外:

    java.lang.ClassNotFoundException 此异常表示在类路径中找不到该类.这表明我们正在尝试加载类定义,并且类在路径上不存在.

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


感谢您提及NoClassDefFoundError的原因,这对我帮助很大!在我的情况下,之前抛出了ExceptionInInitializerError,这就是我如何发现静态块中的错误.

2> Mocky..:

这是因为当您的代码依赖于类文件并且它在编译时出现但在运行时未找到时.查找构建时和运行时类路径的差异.


这个答案不一定正确,会让很多人误导!请参阅以下Jared的更好答案.
@DaveL.谢谢!Jared的回答有400多个upvotes如下!一个答案是-4 up(down?)投票高于它.SO的答案排序逻辑有些可疑.

3> xli..:

这是代码来说明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;
}


原因是在第一次尝试之后jvm已经知道它不会工作并且第二次抛出不同的异常?
@PhilipRego不确定“纯” NoClassDefFoundError的含义。第一次调用新的SimpleCalculator()时,您会收到一个由ArithmeticException引起的ExceptionInInitializerError。第二次调用`new SimpleCalculator()`时,您会得到一个NoClassDefFoundError,其纯度与其他任何一种一样。关键是您可以由于运行时不在类路径上而不是SimpleCalculator.class的原因而获得NoClassDefFoundError。

4> Virtual..:

NoClassDefFoundError在Java中

定义:

    Java虚拟机无法在运行时找到在编译时可用的特定类.

    如果在编译期间存在类,但在运行时期间在java类路径中不可用.

在此输入图像描述

例子:

    该班是不是在类路径,就知道它,但很多时候没有出手肯定的方式你可以看看打印System.getproperty("java.classpath"),它会打印类路径从那里,你至少可以得到了解您的实际运行时类路径.

    NoClassDefFoundError的一个简单的例子是类属于丢失的JAR文件或JAR未添加到类路径或有时罐子的名字已被改变的人喜欢在我的情况下,我的一个同事已经改变tibco.jar到tibco_v3.jar和程序失败的java.lang.NoClassDefFoundError,我想知道什么是错的.

    只是尝试使用显式的-classpath选项和你认为可行的类路径一起运行,如果它正在工作那么这是一个确定的短信,表明某人正在重写java类路径.

    JAR文件的权限问题也可能导致Java中的NoClassDefFoundError.

    XML配置错误也可能导致Java中的NoClassDefFoundError.

    当你在一个包中定义的编译类在加载时不会出现在同一个包中,就像在JApplet中一样,它会在Java中抛出NoClassDefFoundError.

可能的解决方案:

    该类在Java Classpath中不可用.

    如果您在J2EE环境中工作,那么多个Classloader中的Class的可见性也会导致java.lang.NoClassDefFoundError,请参阅示例和场景部分进行详细讨论.

    检查日志文件中的java.lang.ExceptionInInitializerError.由于静态初始化失败而导致的NoClassDefFoundError非常常见.

    因为NoClassDefFoundError是java.lang.LinkageError的子类,所以如果其中一个依赖项(如本机库)可能不可用,也会出现这种情况.

    任何启动脚本都会覆盖Classpath环境变量.

    您可能正在使用jar命令运行程序,并且未在清单文件的ClassPath属性中定义类.

资源:

解决NoClassDefFoundError的3种方法

java.lang.NoClassDefFoundError问题模式



5> shsteimer..:

我发现,有时我得到一个NoClassDefFound错误时的代码在运行时发现的类的不兼容的版本编译.我记得的具体实例是apache轴库.实际上有2个版本在我的运行时类路径和它拿起过时和不兼容的版本,而不是正确的,造成NoClassDefFound错误.这是在命令行应用程序中我使用类似于此的命令.

set classpath=%classpath%;axis.jar

我能够通过使用以下方式获取正确的版本:

set classpath=axis.jar;%classpath%;


有同样的问题.事实证明我用Java7编译了war文件,但是我的Tomcat安装使用的是Java6.我不得不更新我的环境变量
如果这种情况发生,那么我会说Java陷入混乱.+2如果是这样的话.无法验证这一点.如果发现true,则会再次执行+ 1(在评论中)

6> Ram Patra..:

这是我到目前为止找到的最佳解决方案.

假设我们有一个org.mypackage包含类的包:

HelloWorld(主类)

SupportClass

UtilClass

并且定义此包的文件存储在目录D:\myprogram(在Windows上)或/home/user/myprogram(在Linux上)下.

文件结构如下所示: 在此输入图像描述

当我们调用Java时,我们指定要运行的应用程序的名称:org.mypackage.HelloWorld.但是,我们还必须告诉Java在哪里查找定义包的文件和目录.因此,要启动该程序,我们必须使用以下命令: 在此输入图像描述



7> Nikhil Sahu..:

我使用Spring框架与Maven的,在我的项目解决了这个错误.

类中存在运行时错误.我正在读取一个属性为整数,但是当它从属性文件中读取值时,其值为double.

Spring没有给我一个关于运行时失败的哪一行的完整堆栈跟踪.它简单地说NoClassDefFoundError.但是当我将它作为本机Java应用程序(从MVC中取出)执行时,它给出了ExceptionInInitializerError哪个是真正的原因,这就是我如何跟踪错误.

@ xli的回答让我深入了解了我的代码可能出错的地方.



8> codeDr..:

当运行时类加载器加载的类无法访问java rootloader已经加载的类时,我得到NoClassFoundError.因为不同的类加载器位于不同的安全域中(根据java),jvm将不允许在运行时加载器地址空间中解析已由rootloader加载的类.

用'java -javaagent:tracer.jar [你的java ARGS]'运行你的程序

它生成显示已加载类的输出,以及加载类的加载器env.这非常有用,可以追踪无法解决课程的原因.

// 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;
            }
        });
    }
}



9> Bartek Lipin..:

您可能会看到很多有趣的情况NoClassDefFoundErrors是,当您:

    throw一个RuntimeExceptionstatic你的类的块Example

    拦截它(或者如果它像在测试用例中抛出一样没关系)

    尝试创建此类的实例 Example

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
    }
}

NoClassDefError将与ExceptionInInitializerError从静态块一起抛出RuntimeException


当您NoClassDefFoundErrorsUNIT TESTS中看到时,这尤其重要。

在某种程度上,您是“共享” static测试之间的块执行,但是最初ExceptionInInitializerError只是在一个测试用例中。第一个使用有问题的Example类。使用Example该类的其他测试用例只会抛出NoClassDefFoundErrors


这是现实生活中非常有用的建议。我只是在使用类属性初始化程序时遇到了同样的情况。您只有一次机会在日志中看到实际的问题。加载(或尝试尝试)该类后,您需要重新启动所有内容。
推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有