java.lang.NoClassDefFoundError: Could not initialize class

Posted cdfive

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java.lang.NoClassDefFoundError: Could not initialize class相关的知识,希望对你有一定的参考价值。

今天线上环境发现storm任务日志里有如下异常:
java.lang.NoClassDefFoundError: Could not initialize class... 某依赖工程X一个工具类方法
堆栈信息里找到某dubbo服务A的某方法具体某行抛出的,查看服务A的日志,也有该异常信息。

在服务A的工程里找到那行代码,是某个计算分支里,的确调用了工程X的一个工具类方法。
有些奇怪,因为这个工具类方法调用已上线运行很久了,以前都没这个异常。

打开工程X的工具类方法,该工具类没有构造函数,即使用默认的。
注意类前面有一个static Logger定义,private static Logger LOGGER = LogFactory.getLogger(XXX.class),该Logger是项目基础组件封装的,不是slf4j、common-logging等第三方包里的类;
因为static变量在类初始化时先加载,结合异常信息,那么很有可能就是这个static变量初始化失败了。

查看git提交记录,想起上周有同学改动过,对几个记录日志的方法内部增加了些逻辑,主要是增加记录的字段,同时为了记录catch中的异常,增加了这个Logger。

工程X是个common包,被各个dubbo工程引用。

查看工程X的依赖,发现如下依赖顺序,X->Y->Z->Logger组件。

查看服务A工程的依赖,依赖A->X并排除了Y,而A并没有直接依赖Logger组件。

那么问题找到了,原因是服务A缺少Logger基础组件依赖,但调用工程X工具类的static变量用到Logger基础组件中的类。

解决方法想到两种:

1.修改工程X该工具类,基础组件的Logger改为用slf4j或common-logging等第三方的Logger;

2.工程X增加Logger组件的依赖。

这里想吐槽下公司的依赖管理,可以说非常混乱了:
基础组件依赖了大量第三方组件,依赖配置的顺序较混乱,有些依赖完全没用上;
业务dubbo工程的依赖也较混乱,各种依赖exclude,并且配置顺序较混乱。
想改变很困难,几年下来的工程,明显没有代码review,估计领导也不重视,
基础代码中的很多作者都不在公司了,2011、2012年的创建时间... 后来接锅者表示╮(╯▽╰)╭

考虑到工程X未来可能需要基础组件的Logger依赖,选择了第2种方式。


总结:

遇到该异常,除了检查异常信息中的类在依赖中是否存在,很大可能就是类里某static变量或static代码块,它的相关依赖类可能不存在。






以上是关于java.lang.NoClassDefFoundError: Could not initialize class的主要内容,如果未能解决你的问题,请参考以下文章