背景

一个新的项目引入之前自定义封装的一个日志采集JAR包。在引入完成后启动出现如下问题:

这里是引用Logging system failed to initialize using configuration from ‘classpath:logback-spring.xml’

java.lang.IllegalStateException: Logback configuration error detected:
 Failed to instantiate converter class [comXXX.log.config.LogMessageConverter] for keyword [msg] ch.qos.logback.core.util.DynamicClassLoadingException: Failed to instantiate type com.log.config.LogMessageConverter

问题排查实践

【1】检查logback-spring.xml配置文件
检查logback-spring.xml配置文件是否存在,检查结果存在;
检查当前项目是否有其他logback.xml文件,检查结果无异常

【2】根据错误描述检查logback-spring.xml文件中[msg]配置是否存在

Java运行jar 并指定 prod_jar


检查结果正常,配置正常

【3】使用一个其他的项目测试引入该日志采集JAR,检查是否正常,经过测试正常

【4】根据错误描述,定位到具体出现的源码位置:

Java运行jar 并指定 prod_java_02


观察错误信息可以看到错误类:

ch.qos.logback.core.pattern.parser.Compiler

并根据错误输出信息定位到具体的代码位置

Java运行jar 并指定 prod_jar_03


以上就是具体发生异常的位置,其中converterMap是核心的容器,其保存了logback中转换器key名称以及对应的转换类,通过观察该容器可以看到配置文件正常被加载,容器信息如下所示

Java运行jar 并指定 prod_Java运行jar 并指定 prod_04


继续跟踪代码位置

Java运行jar 并指定 prod_java_05


最终定位到问题所在,因为这里的类加载器加载自定义转换器时发生异常,无法加载该类。

以下是异常信息,看到这个信息终于清楚问题所在了,被引入的日志jar包要求使用jdk11运行环境,但是当前的项目使用的是jdk8的环境,其中jdk8的字节码文件的标识版本号就是52,如此在切换JDK版本后问题解决,正常运行了

com/log/config/LogMessageConverter has been compiled by a more recent version of the Java Runtime (class file version 55.0), this version of the Java Runtime only recognizes class file versions up to 52.0

Java运行jar 并指定 prod_spring_06

小结

【1】本次的问题主要是因为在使用扩展JAR包时不细心,没有仔细检查JDK版本的要求,以后在使用非官方或者自定义的JAR包时要注意这一点,另外,要养成深究问题的思维,要多思考多实践。
【2】此外,对于Class文件的版本号一定要有敏感度,比如52对应的是JDK1.8,版本号55是JDK11。