引子

2021 年 12 月 10 日,网上曝出 log4j2 远程代码执行漏洞,引发几乎所有公司紧急修复线上安全漏洞,在修复漏洞过程中,偶然发现一个 springboot 低版本与 log4j2 高版本之间的兼容性错误,在此记录下解决过程。

环境情况

spring-boot-starter-log4j2 版本:1.5.9

log4j2 版本:2.15.0

log4j2.xml 文件位置:classpath:log/log4j2.xml

案发现场

以上版本的搭配,应用启动时报以下的错误:

2021-12-26 13:42:28,386 main ERROR Error creating converter for xwEx java.lang.reflect.InvocationTargetException

Caused by: java.lang.NoSuchMethodError: org.apache.logging.log4j.core.pattern.ExtendedThrowablePatternConverter.newInstance([Ljava/lang/String;)Lorg/apache/logging/log4j/core/pattern/ExtendedThrowablePatternConverter;

2021-12-26 13:42:28,388 main ERROR Unrecognized conversion specifier [xwEx] starting at position 161 in conversion pattern.

网上搜索此错误,得到以下结果:

结论:都是 springboot 与 log4j2 版本不兼容,

解决方案:升级 springboot 版本。

但目前的问题是,springboot 版本不能升级,否则会面临更多未知的兼容性问题,因此只能向 log4j2 动手了。

排查过程

首先从报错信息上可以看出,这是 log4j2 的异常,理论上来说对于 springboot 应用本身应该没有影响。从应用启动的日志中也能确认,虽然抛出了以上异常信息,但是应用仍然正常启动了,请求响应也正常。

其次,从报错信息中可以大致确认原因,log4j2 在转换 xwEx 这个字符串时异常,猜测这个字符串应该是老版本支持的,新版本不支持了,所以报了这个错。

虽然大致定位了问题,但是诡异的事情又发生了,应用中定义的 log4j2.xml 文件中并没有使用 xwEx 这个字符串。那就是说项目中还存在其他的 log4j2.xml 文件,于是全局搜索了一番,果然不出所料:

image-f9adfd41.png打开看下:

image-251d6146.png终于找到罪魁祸首了。

问题解决

定位了问题之后,共找到两种解决方案:

  1. 应用本身的配置文件中,定义名为 Console 的 Console Appender,可以起到覆盖 springboot log4j2.xml 中配置的效果。

  2. 将应用中的 log4j2.xml 文件放到 classpath 下,可以直接覆盖掉 springboot 的 log4j2.xml。