ClassNotFoundException和NoClassDefFoundError的区别:
ClassNotFoundException:
- 它是Exception,不是Error在Throwable体系中只是一个Exception,说明它是可恢复的
- 发生的时机
- 当应用试图通过给定的name加载对应的class时可能抛出此异常,找不到对应的class文件时抛出
- Class.forName(name);
- ClassLoader.findSystemClass();
- ClassLoader.loadClass();
- 当应用试图通过给定的name加载对应的class时可能抛出此异常,找不到对应的class文件时抛出
NoClassDefFoundException
- Error级别,比Exception要严重
- JVM或者ClassLoader试图加载一个class的definition的时候,找不到对应的class的definition,通常时new A()的时候
因此,当源文件编译成功,但是运行时找不到需要的class文件时,会出现NoClassDefFoundError。这可能会发生在一个分布式或者生产的JAR中,里面没有包含所有的需要的class文件。
一个预期编译时期没问题的程序在不能运行可能是由于class文件找不到或者和编译期生成或者面临的不相同。这是一个非常严重的错误,程序不能被JVM启动。
当对应的class文件不能被类加载器找到的时候会抛出ClassNotFoundException,通常情况class在class path下找不到,也有可能是这个class试图被父类加载器加载的一个class加载,但是这个class只对子类加载器可见。这种情况通常出现在比较复杂的环境中。
人们经常搞混NoClassDefFoundError和ClassNotFoundExcepion,然后两者大不相同。
java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory
这并不意味着ActiveMQConnectionFactory的class文件在classpath下找不到。实际上恰恰相反,这意味ActiveMQConnectionFactory的class是可以被类加载器找到的,但是在试图加载这个类的时候,读取class的definition时出现了错误。一般情况下当class中有静态代码库或者静态字段时,而这些静态代码使用了当前类加载器找不到的class时,会出现这样的问题。因此为了找到罪魁祸首,查看问题中class的源码,找其中用到的静态代码块和静态字段,如果不能访问源码,试图反编译它。
代码举例,下面这行代码,确保SomeClass的class在classpath中。
private static SomeClass foo = new SomeClass();
代码地址见此处