引子
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 文件,于是全局搜索了一番,果然不出所料:
打开看下:
终于找到罪魁祸首了。
问题解决
定位了问题之后,共找到两种解决方案:
应用本身的配置文件中,定义名为 Console 的 Console Appender,可以起到覆盖 springboot log4j2.xml 中配置的效果。
将应用中的 log4j2.xml 文件放到 classpath 下,可以直接覆盖掉 springboot 的 log4j2.xml。