SpringBoot2.7照旧任性的,就是不支持Logback1.3,你能奈他何
开心一刻今天上午,同事群中的刘总私聊我
刘总:你来公司多久了
我:一年了,刘总
刘总:你还年轻,机会还许多,年底了,公司要裁员
刘总苦口婆心的继续说到:以后我们常接洽,无论以后你遇到什么困难,找我,我会尽量帮你!
我:所以了,我是被裁了吗,呵,我爸知道吗?
刘总:知道,今天上午保安部已经出名单了,你爸也在内里
我:我妈知道吗?
刘总:保洁也裁
我:刘总,你做这些事变问过我爷爷吗?
刘总:门卫也裁
我内心咯噔一下,这它妈哒团灭了呀
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100455601-211500067.jpg安全漏洞
公司的测试部门会定期扫描代码,检测出安全漏洞,导出 Excel放到群里,各个项目的负责人针对性去修复(升级组件版本),因为某些原因不能修复的,需要给出原因(有些组件版本依靠更高的 JDK 版本,而 JDK 又不能升)。而我负责的项目是基于 Spring Boot 2.7.18,它依靠的 logback 版本是 1.2.12,存在安全漏洞 CVE-2023-6378
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100515886-865090246.png我本意是非常拒绝修这玩意的,修的时候得评估影响点,测的时候需要都覆盖到;核心组件的升级不亚于一次重构,开发和测试都得全量测。重点是,修好不算产出,修坏了可是要背锅的,我可是履历过血的教导的:都说了能不动就别动,非要去调解,出生产事故了吧,总之照旧那句话
能不动就不要动,改好没绩效,改出题目要背锅,吃力不讨好,又不是不能跑
纵使我有万般的不愿,但也不得不修,公司对安全漏洞这一块非常重视,毕竟要给客户留下非常专业的形象。既然避无可避,那就坦然接受,充实评估影响点,做好全面的测试
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100602137-1559016452.png漏洞修复
怎样修复,想必各人都知道,剔除掉 spring-boot-starter-logging 依靠,引入新版本依靠,如下所示
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>升级到哪个版本,就值得仔细斟酌一番了。反正都要升级,那何不升级到最新版?安全漏洞少,甚至暂时没漏洞。那也不是,因为 logback 依靠 JDK 版本,官方说明如下
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100650976-694577736.png因为项目依靠的 JDK 版本是 8,所以我们将 logback 升级到 1.3 的最新版是最合适的;logback 1.3.x 依靠的 SLF4J 版本是 2.0.x,所以最终 pom.xml 调解成如下
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<logback.version>1.3.14</logback.version>
<slf4j.version>2.0.7</slf4j.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100716907-1942731245.png貌似挺简单的,对吧?编译也不报错,一切都很顺利;一旦你运行,最烦人的 bug 就来了
Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:304)
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:178)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:171)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:145)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:133)
at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:79)
at org.springframework.boot.SpringApplicationRunListeners.lambda$starting$0(SpringApplicationRunListeners.java:56)
at java.util.ArrayList.forEach(ArrayList.java:1249)
at org.springframework.boot.SpringApplicationRunListeners.doWithListeners(SpringApplicationRunListeners.java:120)
at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:56)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:299)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1300)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1289)
at com.qsl.Application.main(Application.java:15)
Caused by: java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 17 more此时,你们会怎么办?本着快速解决 bug 的原则,我们也只能上网查题目
java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder
看能不能找到解决办法;可一通查下来,各种尝试,该题目都得不到解决,除非将 logback 版本降到 1.2.x,可最新的 1.2.13 是有不少安全漏洞的
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100744787-158509602.png那没别的办法了,只能去追查题目产生的原因了,找到原因就好对症下药了。题目又来了,怎样去查原因了,最直接、最有效的办法就是从异常堆栈信息入手
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100827891-754781675.png鼠标左击 LogbackLoggingSystem.java:304,然后就来到 spring-boot-2.7.18的源码
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100844972-919599812.png这里用到了 StaticLoggerBinder,在往上滑到 LogbackLoggingSystem 的import 部门,StaticLoggerBinder 的全类路径是
org.slf4j.impl.StaticLoggerBinder
logback 1.2.12 是有这个类的
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100907501-1090832201.png但 logback 1.3.14 不仅没有该类,连 org 包都不存在了
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100926169-305287058.png所以,原因是不是找到了?
spring-boot-2.7.18 依靠 org.slf4j.impl.StaticLoggerBinder,而 logback 1.3.14 没有该类
那怎样对症下药了?不仅你们懵,我也懵
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728100948217-359701457.png调解下思路,这个题目我们肯定不是第一个遇到的,对吧,肯定有人在 spring-boot 的官方提问,我们去搜搜 org/slf4j/impl/StaticLoggerBinder
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101008784-979104782.png点进去,内里有官方职员给出的答复,我给各人翻译一下;提问者是 LSmyrnaios,他做了一下背景介绍
logback 1.3.x 基于 Java 8,1.4.x 基于 Java-11,而 Spring Boot 只在 3.x.x 中集成了 logback 1.4.x(基于 Java-11)
Java-8 用户被遗忘了
根据 logback 文档说明,logback 同时维护 1.3.x 和 1.4.x,也就是说,logback 1.3.x 是 '活泼的',Spring Boot 2.7.x 应该集成它
请考虑以下案例:
我有一个Java-8应用步伐,利用 logback v.1.3.6,运行没题目
如今,我想将该应用步伐集成到 Spring Boot v.2.7.9,运行的时候胞如下错误:
(异常堆栈跟我们遇到的一样,不展示了)
看起来像是 Spring Boot 用的 slf4j 1.7.x,但是 logback 1.3.x 用的 slf4j 2.0.x,所以 StaticLoggerBinder 类不见了
所以,你们能够在 Spring Boot >= 2.7.x and < 3 的版本中支持 logback 1.3.x 吗
先谢谢了.
这么看来,这哥们遇到的题目跟我们的一样,提出的诉求也跟我们一样,是不是看到了盼望?
官方职员 scottfrederick 给出了复兴
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101039442-908253182.png翻译过来就是
LSmyrnaios 感谢你的接洽。 Spring Boot 2.7.x 依靠 Logback 1.2.x。 已经在第三方升级政策中说明过了,我们不会在 2.7.x 的版本中升级 Logback到 1.3.x。正如你提到的,我们不仅仅要升级 Logback 到 1.3.x,还需要将 SLF4J 升级到 2.0.x,这有一个关于我们为什么不在 2.7.x 升级的讨论,所以我们做补丁发布
第三方依靠升级说明如下
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101100989-949072114.png简单点来说就是:第三方依靠的补丁级别的修复,可以在 Spring Boot 的补丁版本中升级,而第三方依靠的次要大概重要版本的升级,则只能在 Spring Boot 的次要或重要版本中升级。不能在 Spring Boot 的补丁版本中升级第三方依靠的次要大概重要版本。这里的补丁版本可以理解成小版本,也就是 1.2.x 中的 x,而次要大概重要版本,则是 1.x.x 中的第一个 x,也就是我们所说的大版本
关于 scottfrederick,他可不是 Spring Boot 的平凡 Contributor,人家可是榜六大哥
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101119626-1375286722.png他说的照旧很有权势巨子的;关于他提到的讨论,我们后面在看,先把当前的看完。提问者 LSmyrnaios 又说了
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101138664-1021335919.png翻译过来就是
scottfrederick,我们接着刚刚的讨论,我想问的是,是否有大概在 Spring Boot 的下一个大版本(比如 2.8.0,如果在计划中的话)将 SLF4J 升级到 2.0.x,logback 升级到 1.3.x
这对于大量的 Java 8 用户来说非常重要,他们盼望为生产系统提供最新的安全和错误修复
先谢谢了
scottfrederick 说的就很符合我们的盼望,我们接着往下看。wilkinsona 给出了复兴
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101205444-1523781417.png翻译过来就是
目前没有 Spring Boot 2.8 的计划
言简意赅,弦外之音就是 Spring Boot 2.x.x 就是不支持 Logback 1.3.x,满满的任性感。你们是不是很好奇这任性的哥们是谁?人家可是 Spring Boot 的榜一大哥!!!
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101220613-1739660025.png是不是觉得他任性的天经地义了?我们继续往下看,ASarco 说了一句
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101250225-1743641587.png翻译过来就是
如今的题目是 logback 1.2.12 存在安全漏洞 cve-2023-6378,对于 2.7.x 的煞笔用户却没有一个结论
这哥们表达了自己得愤懑,都直接飙国粹(SB)了,那是相当的气愤呀
SB 是 Spring Boot 的简写,并非国粹,各人别被误导了!!!
针对 ASarco 的题目,后面有人给了复兴,可以升级 Logback 到 1.2.13 来修复漏洞 cve-2023-6378,而我们也没得选了,只能将 Logback 从 1.3.14 降到 1.2.13,最终的 pom.xml 如下所示
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<logback.version>1.2.13</logback.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-logging</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
</dependencies>所以,1.2.13 的安全漏洞还是存在的,下次扫描出来后我们直接说明如下
修复不了,Spring Boot 2.7.x 官方不计划支持 Logback 1.3.x,除非升级 Spring Boot 到 3.x.x(集成的是 Logback 1.4.x),但同时需要将 JDK 升级到 11
讨论
还记得前面提到的谁人讨论吗,因为比较长,我挑一些重点给各人翻译下
1、wilkinsona 提到了 Logback 的一次 commit,这次提交移除了 StaticLoggerBinder
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101339588-704623785.png从 1.3.0-alpha0 版本就移除了 StaticLoggerBinder,所以 Spring Boot 2.7.x 不能集成 Logback 1.3.x 的任何一个版本
2、snicoll (榜二大哥) 提到了一个很重要的点
https://img2024.cnblogs.com/blog/747662/202407/747662-20240728101401634-940750051.pngSpring Boot 的 LoggingSystem 是可以禁用大概改变的
-Dorg.springframework.boot.logging.LoggingSystem=none
3、wilkinsona 提到了 spring.factories 中的 ApplicationListener,其优先级高于 org.springframework.boot.context.logging.LoggingApplicationListener,可以用来设置系统属性以响应 ApplicationStartingEvent
4、wilkinsona 针对 cmuchinsky 提出的
对于 spring boot 2.7,是否有大概更新 ogbackLoggingSystemlogback 来兼容 Logback 1.3 与 1.2,例如反射
给出了回答,他以为这不太大概,支持 Logback 1.4 所需的更改范围太广,无法通过反射并行支持 1.2 和 1.3/1.4
5、zhaolj214 通过读源代码,找到了一种解决方案
@SpringBootApplication
public class Spring5Application {
public static void main(String[] args) {
System.setProperty("org.springframework.boot.logging.LoggingSystem", "none");
SpringApplication.run(Spring5Application.class, args);
}
}至于精确与否,我们下篇再试
6、wilkinsona 说明白可以自定义日志:howto.logging
总结下来就是:针对 Spring Boot 2.7.x,官方不会支持 Logback 1.3.x,但照旧可以通过自定义的方式去支持 Logback 1.3.x,详细怎样自定义,以及结果怎样,且听下回分解
总结
[*]Logback 1.3 依靠 JDK 8,1.4 依靠 JDK 11;Spring Boot 2.7.x 依靠 Logback 1.2.x,而 3.x.x 依靠 Logback 1.4.x。也就说 Spring Boot 跳过了 Logback 1.3.x
[*]Spring Boot 官方也给出了答复,根据第三方依靠政策(小版本升级小版本,大版本升级大版本),2.7.x 不会支持 Logback 1.3.x,而 3.x.x 索性直接支持 Logback 1.4.x
[*]非要 Spring Boot 2.7.x 支持 Logback 1.3.x 也不是不可以,需要调解配置,还存在一些限制,详细细节请看下篇
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页:
[1]