【一零踩坑小记】java运行后NoClassDefFoundError:Initializer fail

By | 3月 24, 2020

本次是对一次踩坑的记录,事情起因,一台服务器在部署完代码后重启后突然部分接口出现了500错误,NoClassDefFoundError:com.xx.xxx,对于这种报错,是因为在编译的时候Java虚拟机找到了这个类,但是在运行的时候未找到这个类,注意跟NoClassFoundError区分开。

当遇到这个问题时,我首先查看了应用日志,发现流程执行过程中到了某个地方就中断了,没有发现详细的报错日志。于是找到WebSphere的系统日志,发现了里面的详细日志,根据cause by提示在将变量值转为int时因为输入的字符串“SD”导致报错,去找到对应的源码,发现在调用A方法时报错了,在看系统日志SystemOut.log里面的其他内容,不同的接口都出现了类似的报错,看打印的详细报错信息,都是因为调用了同一个方法A。

于是我研究了下方法A,输入三个参数,分别是一串数字id,源数据orig和签名数据sign,方法A是一个验签的方法,再往里继续深入查看这个方法,引用了jar包里的内容,就没仔细看下去了,这时脑子突然闪过是不是因为秘钥问题导致的念头,但是因为发现这个方法并没找到什么错误而错过。因为在报错中提示的是将字符串转为Int型时报错了,就考虑说是第一个参数id是不是传入的有问题,因为orig和sign不应该做这种转换,看通过断点及看打印的日志,没发现输入的id参数有什么异常。

于是上网寻求帮助,查看WAS出现这种报错时的原因,看了很多博文后总结了共会有以下几种情况:

WebSphere在重启后出现了内存溢出的情况导致,对于这种情况需要杀掉进程重新启用节点和服务。
因为报错的类存在问题导致,需排查类的情况
JDK版本的问题导致,需查看是否有更新过JDK
可能是由于缺少某个jar包导致
对上面提到的几种情况一一进行了尝试,发现仍然没找到原因,这是有人跟我说昨天找人升级了JDK,于是在想是不是因为JDK的问题导致,不过另一个环境还是正常的,但是解决无果的情况,于是尝试恢复JDK的版本,折腾了一通后发现跟这个没有任何关系。

查来查去没找到原因,怀疑还是跟WAS有关系,于是就将WebSphere上部署的应用及服务全部删除重新安装了一遍,测试了一下发现竟然可以了,很开心觉得问题解决了。但是,过了一会儿查订单发现使用的是另一套环境的数据库,于是将数据库连接改回来后重启后又不行了,让人从天堂又调回了地狱。我突然灵光一现,这肯定是跟数据库的数据有关系,然后想到是秘钥初始化加载到内存里时出现了问题,随后想到之前让测试验证执行的脚本时在数据库里加入了错误的秘钥数据,赶紧去查看数据库的数据,果然在秘钥的字段里发现了报错的两个字符,然后马上删除重启服务,功能恢复正常。

通过这次问题的处理,有以下几点心得:

即使是测试,也不能随便使用一些错误的垃圾数据,不然会给自己挖坑。
根据打印的报错信息排查问题时,如果发现提示报错的方法无问题时,需要在深入排查关联的方法或者依赖的方法是否存在问题。
当你在解决问题时突然闪过一点对某个功能产生怀疑时,最好去排查下,说不定能发现找到问题的关键点。

发表评论

您的电子邮箱地址不会被公开。