在日常Java开发中,我们经常碰到java.lang.NoClassDefFoundError
这样的错误,需要花费很多时间去找错误的原因,而且我们很容易把java.lang.NoClassDefFoundError
和java.lang.ClassNotfoundException
这两个错误搞混,事实上这两个错误是完全不同的。
NoClassDefFoundError的原因
NoClassDefFoundError错误的发生,是因为Java虚拟机在编译时能找到合适的类,而在运行时不能找到合适的类导致的错误。例如在运行时我们想调用某个类的方法或者访问这个类的静态成员的时候,发现这个类不可用,此时Java虚拟机就会抛出NoClassDefFoundError错误。与ClassNotFoundException的不同在于,这个错误发生只在运行时需要加载对应的类不成功,而不是编译时发生。
ClassNotFoundException的原因
ClassNotFoundException是在编译的时候在classpath中找不到对应的类而发生的错误。可能发生在使用反射的地方,spring容器加载类实例时也可能发生这种情况。ClassNotFoundException比NoClassDefFoundError容易解决,是因为在编译时我们就知道错误发生,并且完全是由于环境的问题导致。
怎么解决NoClassDefFoundError错误
根据前文,很明显NoClassDefFoundError的错误是因为在运行时类加载器在classpath下找不到需要加载的类,所以我们需要把对应的类加载到classpath中,或者检查为什么类在classpath中是不可用的,这个发生可能的原因如下:
- 对应的Class在Java的classpath中不可用
- 你可能用jar命令运行你的程序,但类并没有在jar文件的manifest文件中的classpath属性中定义
- 可能程序的启动脚本覆盖了原来的classpath环境变量
- 因为NoClassDefFoundError是
java.lang.LinkageError
的一个子类,所以可能由于程序依赖的原生的类库不可用而导致 - 检查日志文件中是否有
java.lang.ExceptionInInitializerError
这样的错误,NoClassDefFoundError有可能是由于静态初始化失败导致的 - 如果你工作在J2EE的环境,有多个不同的类加载器,也可能导致NoClassDefFoundError