java.lang.NoClassDefFoundError 和 java.lang.ClassNotFoundException 都是 Java 语言定义的标准异常。从异常类的名称看似乎都跟类的定义找不到有关,但是还是有些差异。我们先来看一下 java 规范中对这两个异常的说明:
java.lang.NoClassDefFoundError:
The searched-for class definition existed when the currently executing class was compiled, but the definition can no longer be found.
类加载器试图加载类的定义,但是找不到这个类的定义,而实际上这个类文件是存在的。
java.lang.ClassNotFoundException:
1. The forName method in class Class.
2. The findSystemClass method in class ClassLoader .
3. The loadClass method in class ClassLoader.
but no definition for the class with the specified name could be found.
从规范说明看, java.lang.ClassNotFoundException 异常抛出的根本原因是类文件找不到。
另外,从两个异常的定义看,java.lang.NoClassDefFoundError 是一种 unchecked exception(也称 runtime exception),而 java.lang.ClassNotFoundException 是一种 checked exception。(区分不了这两类异常?看这里 checked exception vs unchecked exception)
----------
有了前面的分析,我们知道这他们是两个完全不同的异常。但是如果在实际运行代码时碰到了其中一个,还是很容易被混淆成同一个,尤其是当事先没有留意到这两个异常的差别时。
就我个人而言,在这两个异常里,平时碰到最多的是 java.lang.ClassNotFoundException。从异常的名字看,很容易理解这个异常产生的原因是缺少了 .class 文件,比如少引了某个 jar,解决方法通常需要检查一下 classpath 下能不能找到包含缺失 .class 文件的 jar。
但是,很多人在碰到 java.lang.NoClassDefFoundError 异常时也会下意识的去检查是不是缺少了 .class 文件,比如 SO 上的这位提问者(java.lang.NoClassDefFoundError: Could not initialize class XXX)-- “明明 classpath 下有那个 jar 为什么还报这个异常“。而实际上,这个异常的来源根本不是因为缺少 .class 文件。而碰到这个异常的解决办法,一般需要检查这个类定义中的初始化部分(如类属性定义、static 块等)的代码是否有抛异常的可能,如果是 static 块,可以考虑在其中将异常捕获并打印堆栈等,或者直接在对类进行初始化调用(如 new Foobar())时作 try catch。
----------
前两天我也碰到了一个类似场景导致的 java.lang.NoClassDefFoundError: Could not initialize class xxx 异常,下面详细记录一下。
我定义了一个类,为了使用 log4j 打印日志,调用 org.slf4j.LoggerFactory 创建了一个 Logger,并作为类的 static 属性,除此之外无其他的成员属性,代码如下:
public class Foo { private static Logger logger = LoggerFactory.getLogger(Foo.class); // ... methods }
在另一个类里创建 Foo 实例:
public class Bar { public void someMethod() { Foo foo = new Foo(); // ... } }
在执行 new Foo() 时抛异常 java.lang.NoClassDefFoundError: Could not initialize class Foo。经过一番排查,这个异常最后的原因出在了 LoggerFactory.getLogger(Foo.class) 调用抛错,关于 这条语句为什么会抛错,我会在另一篇文章里详细描述,在这里只是简单的说下原因:由于 slf4j-api.jar 和 slf4j 的某个 binding jar 版本不兼容所致。
----
总结,记住他们是两个不同的异常类,在碰到具体某个异常时,从名字并联系它的 message 信息(如 "Could not initialize class ")就很容易锁定问题来源。
完。
相关推荐
文章目录: Java异常架构与异常关键字 Java异常简介 Java异常架构 1. Throwable 2. Error(错误) ...6. NoClassDefFoundError 和 ClassNotFoundException 区别? 7. try-catch-finally 中哪个部分可以省略?
java.lang.NoClassDefFoundError: com/sun/activation/registries/LogSupport异常处理
整个系统都没有错误,但是在发布运行后,控制台上却抛出了这样的异常: java.lang.ClassNotFoundException: org.apache.commons.dbcp.BasicDataSource
他们提供的见解有助亍理解和解决常见的 Java 异常,例如 NoClassDefFoundError 和 ClassNotFoundException,以及更有挅戓性的问题,例如类装入器约束迗反和死锁。在第 1 部分中,他们详细描述了 Java 类装入的工作...
当flink on yarn模式运行时,发生如下异常信息,需要将压缩包中的4个依赖jar包放入flink安装路径下的lib目录下。 Exception in thread "main" java.lang.NoClassDefFoundError: ...
6. NoClassDefFoundError 和 ClassNotFoundException 区别? 7. try-catch-finally 中哪个部分可以省略? 8. try-catch-finally 中,如果 catch 中 return 了,finally 还会执行吗? 9. 类 ExampleA 继承 Exception...
java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError的区别 Oracle 一个表字段,更新另一个表字段 报 not null PowerDesigner去除引号方法 显示公式和编辑公式的区别 Exception occurred executing ...
云端同步由于某些问题(不兼容),当我添加Firestore依赖项时(所有/ auth -ui类都抛出了运行时异常,NoClassDefFoundError和ClassNotFoundException),我注释掉了使用Firestore的部分,仅使用了ROOM。 您可以在...
类加载器是 Java 语言的一个创新,也是 ...不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时间去调试 ClassNotFoundException和 NoClassDefFoundError等异常。
类加载器是 Java 语言的一个创新,也是 ...不过如果遇到了需要与类加载器进行交互的情况,而对类加载器的机制又不是很了解的话,就很容易花大量的时间去调试 ClassNotFoundException和 NoClassDefFoundError等异常。
1. 没有找到类的异常(NoClassDefFoundError) 异常如下: Exception in thread "main" java.lang.NoClassDefFoundError: com/google/common/base/Function at com.yy.baidu.testBaidu.main(testBaidu.java:12)...
注意!!!!这个jar仅支持commons-lang-3.x 注意!!!!这个jar仅支持commons-lang-3.x ...Caused by: java.lang.ClassNotFoundException: org.apache.commons.lang.exception.NestableRuntimeException
异常四. Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/LoggerFactory Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory 缺少 slf4j-api-1.7.6.jar 包