zoukankan      html  css  js  c++  java
  • 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有改动并上线。

    工程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年的创建时间... 后来接锅者表示╮(╯▽╰)╭
    

    其实第1种方法要好一些,基础组件不应该有大量依赖,但是很多其他工程在引用,改依赖风险较大;
    再考虑到工程X未来可能需要基础组件的Logger依赖,选择了第2种方式。


    总结:

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

  • 相关阅读:
    同一个IIS绑定多个Htts 站点问题
    开发小程序心得
    在阿里云里申请免费Https证书SSL
    request:fail 小程序要求的 TLS 版本必须大于等于 1.2
    js封装Cookie操作
    数据库日志文件(databasename_log.ldf)太大 如何清除
    sql with(lock) 与事务
    java.lang.VerifyError: com/google/android/gms/measurement/internal/zzw
    Eclipse 导入 Android studio Exception Ljava/lang/UnsatisfiedLinkEror
    Eclipse工程 导入 Android Studio
  • 原文地址:https://www.cnblogs.com/cdfive2018/p/10241714.html
Copyright © 2011-2022 走看看