记录一次线上问题,调用静态方法出现java.lang.NoClassDefDoundError:xxx/xxx/xxx/xxx/类名 异常

场景描述

最近上线了一个项目,本地 编译+运行 都是没有任何错误或者异常,但是 一旦部署到线上 ,就会出现NoClassDefDoundError 错误

错误模拟
java.lang.NoClassDefDoundError:xxx/xxx/xxx/xxx/A 

问题分析

注意:该场景分析指针对静态方法而言。
我们都知道 NoClassDefDoundError:xxx 错误的出现 ,本质上是jvm在运行时,找不到相应的类。
那这个类为什么不在编译的时候不会报出来呢?之所以没报出来,是和类的加载机制有关系。
一般情况下,当我们调用一个静态方法时,jvm根据ClanderUrl,只会校验 该静态方法所在的这个类是否存在,而不会再去校验该类中所依赖的其它类是否存在,这才导致 在编译时期检查不出该问题。

第一次尝试解决

我们经过刚才的那波分析,大致已经了解了问题的本质 ,便根据 场景描述中

java.lang.NoClassDefDoundError:xxx/xxx/xxx/xxx/A 

去查找编译好的A类class文件是否存在 ,发现存在(事实还原),感觉应该没问题了吧,部署到线上,运行。

悲剧重现

部署完成后 ,进行测试 ,然后 发现 ,卧槽!!! 居然 没解决 !
连续测试 ,查看日志,可结果依然是

java.lang.NoClassDefDoundError:xxx/xxx/xxx/xxx/A 

再次分析

此时,心里很郁闷,自己明明检测过了,没问题 为什么还会出现这个问题 ,于是 循环上一步 ,检查编译产物,发现还是没问题,继续部署 。
由于上次部署的教训,这次部署时,严谨对待每一步,时时刻刻盯着日志。
功夫不负有心人,终于发现了不一样 !!!就是 ,在第一次调用的时候,报错信息出现了不同
。出现了

java.lang.NoClassDefDoundError:xxx/xxx/xxx/xxx/B
.....中间省略其它报错信息....
java.lang.NoClassDefDoundError:xxx/xxx/xxx/xxx/A 

此时 ,看到了一个不一样的类,类B !
多次点击测试,发现 只有第一次测试时,才会出现类B的错误提示。于是 猜测是不是 类B的class文件不存在,于是 抱着侥幸的心理去查找类B的 class文件,结果发现 还真没有。
又于是 ,引入类B所在的依赖 ,然后部署。最后结果 居然运行成功了。问题到此解决

问题总结

至于问题发生的原因 在第一次分析的时候 ,已经分析过了,是jvm在运行时 无法找到该类。所以只要引入对应的依赖即可,尤其注意二方包依赖的引用。
关于错误日志 ,该错误日志 ,一定要留意第一次调用时给出的异常信息,关键点很有可能在这里。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值