场景
安全部门针对代码进行漏洞扫描时,发现 logback-core 和 logback-classic 都属于 1.2.x 版本,这个版本存在 cve 漏洞,并且建议升级到 1.3.x 版本。
问题
将两个包直接升级到 1.3.x 版本时,spring boot web 服务启动直接出现错误
exception in thread "main" java.lang.noclassdeffounderror: org/slf4j/impl/staticloggerbinder at org.springframework.boot.logging.logback.logbackloggingsystem.getloggercontext(logbackloggingsystem.java:293) at org.springframework.boot.logging.logback.logbackloggingsystem.beforeinitialize(logbackloggingsystem.java:118) at org.springframework.boot.context.logging.loggingapplicationlistener.onapplicationstartingevent(loggingapplicationlistener.java:238) at org.springframework.boot.context.logging.loggingapplicationlistener.onapplicationevent(loggingapplicationlistener.java:220) at org.springframework.context.event.simpleapplicationeventmulticaster.doinvokelistener(simpleapplicationeventmulticaster.java:176)
原因
org.slf4j.impl.staticloggerbinder 这个类在 1.2.x 中由 logback 自行实现,在1.3.x 版本中,这个类已经消失,
所以直接升级logback的包看起来并不可行,因为spring boot的代码中对实用到了1.2.x中的类。

解决
按照上面所说的原因,直接升级spring boot到新版本就可以支持 logback 1.3.x ,
但是遗憾的是 spring boot 需要版本在 3.x.x 之上才支持 logback 1.3.x ,并且使用 spring boot 3 需要 jdk 17的支持,
这就麻烦了,如此大版本的升级,对于系统的影响,可能无法预知,是否存在不升级版本还能兼容使用 logback 1.3.x 的方法。
最终方案
经过尝试,我使用了下面的步骤,在不升级 spring boot 版本的情况下,成功使用 logback 1.3.x。
1. 单独升级logback版本, pom.xml
<dependency>
<groupid>org.slf4j</groupid>
<artifactid>slf4j-api</artifactid>
<version>2.0.4</version>
</dependency>
<dependency>
<groupid>org.slf4j</groupid>
<artifactid>log4j-over-slf4j</artifactid>
<version>2.0.4</version>
</dependency>
<dependency>
<groupid>org.slf4j</groupid>
<artifactid>jul-to-slf4j</artifactid>
<version>2.0.4</version>
</dependency>
<dependency>
<groupid>ch.qos.logback</groupid>
<artifactid>logback-core</artifactid>
<version>1.3.0</version>
</dependency>
<dependency>
<groupid>ch.qos.logback</groupid>
<artifactid>logback-classic</artifactid>
<version>1.3.0</version>
</dependency>
2. 禁用spring boot自身对日志的适配
@springbootapplication
public class application {
public static void main(string[] args) {
system.setproperty("org.springframework.boot.logging.loggingsystem", "none");
springapplication.run(application.class, args);
}
}
3. 在resources根目录下增加logback.xml文件
这一步根据自己的需求配置饥渴。
<?xml version="1.0" encoding="utf-8"?>
<configuration debug="false">
<property name="app" value="xxx"/>
<property name="filename" value="xxx"/>
<import class="ch.qos.logback.classic.encoder.patternlayoutencoder"/>
<import class="ch.qos.logback.core.rolling.rollingfileappender"/>
<import class="ch.qos.logback.core.rolling.timebasedrollingpolicy"/>
<import class="ch.qos.logback.core.consoleappender"/>
<import class="ch.qos.logback.classic.asyncappender"/>
<import class="ch.qos.logback.classic.filter.thresholdfilter"/>
<appender name="info" class="rollingfileappender">
....
</appender>
<appender name="error" class="rollingfileappender">
.....
</appender>
<appender name="stdout" class="consoleappender">
...
</appender>
....
<appender name="async_info" class="asyncappender">
....
</appender>
....
<appender name="async_error" class="asyncappender">
....
</appender>
<logger name="sun.rmi" level="error"/>
<logger name="sun.net" level="error"/>
<logger name="javax.management" level="error"/>
<logger name="org.redisson" level="warn"/>
<logger name="com.zaxxer" level="warn"/>
<root level="info" additivity="false">
<appender-ref ref="stdout"/>
<appender-ref ref="async_info"/>
<appender-ref ref="async_error"/>
</root>
</configuration>
4. 完毕
这时候启动项目即可正常运行。
原因说明:
slf4j-api 1.8之后的版本不再使用静态绑定,意味着不再需要staticloggerbinder,使用的是serviceloader机制,
新版本的 logback 自然为了适配,删除了 staticloggerbinder,使用 serviceloader 机制,
因此禁用了 spring boot 自身的日志适配,引入高版本logback后,logback自身通过 serviceloader 即引入项目中正常使用
ps
本文参考了:
到此这篇关于springboot2.x漏洞将logback1.2.x 升级至1.3.x的文章就介绍到这了,更多相关logback1.2.x 升级至1.3.x内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论