NoClassDefFoundError原因排查

NoClassDefFoundError错误发生的原因

 NoClassDefFoundError错误的发生,是因为Java虚拟机在编译时能找到合适的类,而在运行时不能找到合适的类导致的错误。例如在运行时我们想调用某个类的方法或者访问这个类的静态成员的时候,发现这个类不可用,此时Java虚拟机就会抛出NoClassDefFoundError错误。与ClassNotFoundException的不同在于,这个错误发生只在运行时需要加载对应的类不成功,而不是编译时发生。很多Java开发者很容易在这里把这两个错误搞混。

简单总结就是,NoClassDefFoundError发生在编译时对应的类可用,而运行时在Java的classpath路径中,对应的类不可用导致的错误。

NoClassDefFoundError和ClassNotFoundException区别

我们经常被java.lang.ClassNotFoundException和java.lang.NoClassDefFoundError这两个错误迷惑不清,尽管他们都与Java classpath有关,但是他们完全不同。NoClassDefFoundError发生在JVM在动态运行时,根据你提供的类名,在classpath中找到对应的类进行加载,但当它找不到这个类时,就发生了java.lang.NoClassDefFoundError的错误,而ClassNotFoundException是在编译的时候在classpath中找不到对应的类而发生的错误。ClassNotFoundException比NoClassDefFoundError容易解决,是因为在编译时我们就知道错误发生,并且完全是由于环境的问题导致。而如果你在J2EE的环境下工作,并且得到NoClassDefFoundError的异常,而且对应的错误的类是确实存在的,这说明这个类对于类加载器来说,可能是不可见的。

引起NoClassDefFoundError错误的原因

1.查看否存在jar冲突,版本不一致问题,即同一个Jar包出现了多个不同版本,并选择了错误的版本而导致JVM加载不到需要的类或加载了错误版本的类;
2.jdk版本不一致,即排查是否存在不同环境jdk版本不一致问题,例如在测试环境正常,生产环境不正常;
3.PATH或CLASS PATH设置有误,这种一般是第一次运行应用,并且所有类都会报此问题;
4.jar包(应用包损坏),确实不存在对应的class文件;
5.其它相关的包有依赖关系没有加到lib中,也即查看对应的应用包中是否存在对应的class文件,查看maven的jar引用配置;
6.如果你工作在J2EE的环境,有多个不同的类加载器,也可能导致NoClassDefFoundError;
7.同一台服务器的其它系统也使用了相关的包并且版本不同,而且是加在classpath或PATH里面的,系统调用的时候先找到了那个jar包;
8.内存不足,maxPermSize或MaxMetaspaceSize设定值过小而加载的类增多引起的,即需要调整相关JVM参数;
9.一种情况就是因为静态变量加载不到原因,即需要加载的类是不是写的有问题,查看具体源码;NoClassDefFoundError也可能由于类的静态初始化模块错误导致,当你的类执行一些静态初始化模块操作,如果初始化模块抛出异常,哪些依赖这个类的其他类会抛出NoClassDefFoundError的错误。如果你查看程序日志,会发现一些java.lang.ExceptionInInitializerError的错误日志,
ExceptionInInitializerError的错误会导致java.lang.NoClassDefFoundError: Could not initialize class
10.可能程序的启动脚本覆盖了原来的classpath环境变量

排查的方法记录

查找jar包是否存在、引用某个类的命令

find ./ -name “*.jar” | xargs grep “xxx”

查看加载了什么类

java -verbose -jar data-rtc-manage-1.0.0.jar

也可以使用 arthas 进行排查

 

参考:
https://blog.csdn.net/weixin_30709809/article/details/97441769
https://yanglinwei.blog.csdn.net/article/details/126322284

 

posted @ 2022-11-29 10:28  天际星痕  阅读(4064)  评论(0编辑  收藏  举报