标签:noclass ali 使用 堆栈 code 提交 comm 顺序 strong
今天线上环境发现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
标签:noclass ali 使用 堆栈 code 提交 comm 顺序 strong
原文地址:https://www.cnblogs.com/cdfive2018/p/10241714.html