NoClassDefFoundError
当我运行我的Java应用程序时,我得到了一个.这通常是什么原因?
虽然这可能是由于编译时和运行时之间的类路径不匹配,但它不一定是真的.
在这种情况下,重要的是要保持两到三个不同的例外:
java.lang.ClassNotFoundException
此异常表示在类路径中找不到该类.这表明我们正在尝试加载类定义,并且类在路径上不存在.
java.lang.NoClassDefFoundError
此异常表示JVM在其内部类定义数据结构中查找了类的定义但未找到它.这与说它无法从类路径加载不同.通常这表明我们之前尝试从类路径加载一个类,但由于某种原因它失败了 - 现在我们正在尝试再次使用该类(因此需要加载它,因为它上次失败了),但是我们'甚至没有尝试加载它,因为我们之前没有加载它(并且合理地怀疑我们会再次失败).较早的失败可能是ClassNotFoundException或ExceptionInInitializerError(表示静态初始化块中的失败)或任何其他问题.关键是,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; }
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问题模式
我发现,有时我得到一个NoClassDefFound错误时的代码在运行时发现的类的不兼容的版本编译.我记得的具体实例是apache轴库.实际上有2个版本在我的运行时类路径和它拿起过时和不兼容的版本,而不是正确的,造成NoClassDefFound错误.这是在命令行应用程序中我使用类似于此的命令.
set classpath=%classpath%;axis.jar
我能够通过使用以下方式获取正确的版本:
set classpath=axis.jar;%classpath%;
这是我到目前为止找到的最佳解决方案.
假设我们有一个org.mypackage
包含类的包:
HelloWorld(主类)
SupportClass
UtilClass
并且定义此包的文件存储在目录D:\myprogram
(在Windows上)或/home/user/myprogram
(在Linux上)下.
文件结构如下所示:
当我们调用Java时,我们指定要运行的应用程序的名称:org.mypackage.HelloWorld
.但是,我们还必须告诉Java在哪里查找定义包的文件和目录.因此,要启动该程序,我们必须使用以下命令:
我使用Spring框架与Maven的,在我的项目解决了这个错误.
类中存在运行时错误.我正在读取一个属性为整数,但是当它从属性文件中读取值时,其值为double.
Spring没有给我一个关于运行时失败的哪一行的完整堆栈跟踪.它简单地说NoClassDefFoundError
.但是当我将它作为本机Java应用程序(从MVC中取出)执行时,它给出了ExceptionInInitializerError
哪个是真正的原因,这就是我如何跟踪错误.
@ xli的回答让我深入了解了我的代码可能出错的地方.
当运行时类加载器加载的类无法访问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; } }); } }
您可能会看到很多有趣的情况NoClassDefFoundErrors
是,当您:
throw
一个RuntimeException
在static
你的类的块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
。
当您NoClassDefFoundErrors
在UNIT TESTS中看到时,这尤其重要。
在某种程度上,您是“共享” static
测试之间的块执行,但是最初ExceptionInInitializerError
只是在一个测试用例中。第一个使用有问题的Example
类。使用Example
该类的其他测试用例只会抛出NoClassDefFoundErrors
。