NoClassDefFoundError和ClassNotFoundException之间的区别是什么?
是什么导致它们被抛出?如何解决这些问题?
在修改现有代码以包含新的jar文件时,我经常遇到这些可抛出的文件。
我已经在客户端和服务器端为一个通过webstart分发的java应用程序击中了它们。
我发现的可能原因是:
未包含在代码客户端build.xml中的包
我们正在使用的新jar缺少运行时类路径
版本与上一个jar冲突
当我今天遇到这些问题时,我采取了一种反复尝试的方法来让事情正常运行。我需要更多的清晰和理解。
与Java API规范的区别如下。
ClassNotFoundException:
当应用程序尝试时抛出
通过类的字符串加载类
名称使用:
类class中的forName方法。
类ClassLoader中的findSystemClass方法。
类ClassLoader中的loadClass方法。
但是没有类的定义
可以找到指定的名称。
NoClassDefFoundError:
抛出如果Java虚拟机或
ClassLoader实例尝试加载
在类的定义中(作为部分)
的正常方法调用或作为的一部分
方法创建一个新实例
表达式)和没有定义的
可以找到类。
搜索的类定义
当前执行时已存在
类被编译,但是定义
再也找不到。
因此,当源代码成功编译时,NoClassDefFoundError似乎发生了,但在运行时,没有找到所需的类文件。这可能发生在JAR文件的分发或生产过程中,其中没有包括所需的所有类文件。
至于ClassNotFoundException,它似乎起源于试图在运行时对类进行反射调用,但程序试图调用的类并不存在。
两者之间的区别是一个是错误,另一个是异常。NoClassDefFoundError是一个错误,它源于Java虚拟机在查找期望查找的类时遇到问题。期望在编译时工作的程序不能运行,因为没有找到类文件,或者与在编译时生成或遇到的类文件不相同。这是一个非常严重的错误,因为该程序不能由JVM启动。
另一方面,ClassNotFoundException是一个异常,所以它在某种程度上是预期的,并且是可以恢复的。使用反射是很容易出错的(因为有一些预期,事情可能不会像预期的那样进行。没有编译时检查来查看所有必需的类是否存在,因此任何查找所需类的问题都会在运行时出现。
从http://www.javaroots.com/2013/02/classnotfoundexception-vs.html:
ClassNotFoundException:类装入器在类路径中找不到所需的类时发生。因此,基本上您应该检查类路径并在类路径中添加类。
NoClassDefFoundError:这更难调试和查找原因。当在编译时存在所需的类,但在运行时类被更改或删除,或者类的静态初始化抛出的异常时,将引发此异常。这意味着要加载的类存在于类路径中,但该类所需的类之一要么被删除,要么被编译器加载失败。你应该看到依赖于这个类的类。
例子:
public class Test1
{
}
public class Test
{
public static void main(String[] args)
{
Test1 = new Test1();
}
}
现在,在编译完这两个类之后,如果删除Test1.class文件并运行Test类,它将抛出
Exception in thread "main" java.lang.NoClassDefFoundError: Test
at Test1.main(Test1.java:5)
Caused by: java.lang.ClassNotFoundException: Test
at java.net.URLClassLoader$1.run(Unknown Source)
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 1 more
ClassNotFoundException:当应用程序试图通过类的名称装入类,但无法找到具有指定名称的类的定义时抛出。
NoClassDefFoundError:如果Java虚拟机试图装入类的定义,但找不到该类的定义时抛出。
当我需要复习的时候,我会一遍又一遍地提醒自己
ClassNotFoundException
类层次结构
ClassNotFoundException extends ReflectiveOperationException extends Exception extends Throwable
在调试
Required jar,类路径中缺少类。
验证所有必需的jar都在jvm的类路径中。
NoClassDefFoundError
类层次结构
NoClassDefFoundError extends LinkageError extends Error extends Throwable
在调试
Problem with loading a class dynamically, which was compiled properly
Problem with static blocks, constructors, init() methods of dependent class and the actual error is wrapped by multiple layers [especially when you use spring, hibernate the actual exception is wrapped and you will get NoClassDefError]
When you face "ClassNotFoundException" under a static block of dependent class
Problem with versions of class.
This happens when you have two versions v1, v2 of same class under different jar/packages, which was compiled successfully using v1 and v2 is loaded at the runtime which doesn't has the relevant methods/vars& you will see this exception. [I once resolved this issue by removing the duplicate of log4j related class under multiple jars that appeared in the classpath]