前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >SpringBoot2.7还是任性的,就是不支持Logback1.3,你能奈他何

SpringBoot2.7还是任性的,就是不支持Logback1.3,你能奈他何

作者头像
青石路
发布于 2024-07-30 04:53:57
发布于 2024-07-30 04:53:57
1.2K00
代码可运行
举报
文章被收录于专栏:开发技术开发技术
运行总次数:0
代码可运行

安全漏洞

公司的测试部门会定期扫描代码,检测出安全漏洞,导出 Excel放到群里,各个项目的负责人针对性去修复(升级组件版本),因为某些原因不能修复的,需要给出原因(有些组件版本依赖更高的 JDK 版本,而 JDK 又不能升)。而我负责的项目是基于 Spring Boot 2.7.18,它依赖的 logback 版本是 1.2.12,存在安全漏洞 CVE-2023-6378

CVE-2023-6378
CVE-2023-6378

我本意是非常拒绝修这玩意的,修的时候得评估影响点,测的时候需要都覆盖到;核心组件的升级不亚于一次重构,开发和测试都得全量测。重点是,修好不算产出,修坏了可是要背锅的,我可是经历过血的教训的:都说了能不动就别动,非要去调整,出生产事故了吧,总之还是那句话

能不动就不要动,改好没绩效,改出问题要背锅,吃力不讨好,又不是不能跑

纵使我有万般的不愿,但也不得不修,公司对安全漏洞这一块非常重视,毕竟要给客户留下非常专业的形象。既然避无可避,那就坦然接受,充分评估影响点,做好全面的测试

干就完了
干就完了

漏洞修复

如何修复,想必大家都知道,剔除掉 spring-boot-starter-logging 依赖,引入新版本依赖,如下所示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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 版本,官方说明如下

logback与jdk关系
logback与jdk关系

因为项目依赖的 JDK 版本是 8,所以我们将 logback 升级到 1.3 的最新版是最合适的;logback 1.3.x 依赖的 SLF4J 版本是 2.0.x,所以最终 pom.xml 调整成如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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>
logback1.3.14
logback1.3.14

貌似挺简单的,对吧?编译也不报错,一切都很顺利;一旦你运行,最烦人的 bug 就来了

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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 是有不少安全漏洞的

logback1.2.13漏洞
logback1.2.13漏洞

那没别的办法了,只能去追查问题产生的原因了,找到原因就好对症下药了。问题又来了,如何去查原因了,最直接、最有效的办法就是从异常堆栈信息入手

异常堆栈
异常堆栈

鼠标左击 LogbackLoggingSystem.java:304,然后就来到 spring-boot-2.7.18 的源码

LogbackLoggingSystem_304
LogbackLoggingSystem_304

这里用到了 StaticLoggerBinder,在往上滑到 LogbackLoggingSystemimport 部分,StaticLoggerBinder 的全类路径是

org.slf4j.impl.StaticLoggerBinder

logback 1.2.12 是有这个类的

logback1.2.12_StaticLoggerBinder
logback1.2.12_StaticLoggerBinder

logback 1.3.14 不仅没有该类,连 org 包都不存在了

logback1.3.14_StaticLoggerBinder不存在
logback1.3.14_StaticLoggerBinder不存在

所以,原因是不是找到了?

spring-boot-2.7.18 依赖 org.slf4j.impl.StaticLoggerBinder,而 logback 1.3.14 没有该类

那如何对症下药了?不仅你们懵,我也懵

懵

调整下思路,这个问题我们肯定不是第一个遇到的,对吧,肯定有人在 spring-boot 的官方提问,我们去搜搜 org/slf4j/impl/StaticLoggerBinder

springboot2.7.x不支持logback1.3.x
springboot2.7.x不支持logback1.3.x

点进去,里面有官方人员给出的答复,我给大家翻译一下;提问者是 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 给出了回复

scottfrederick回复
scottfrederick回复

翻译过来就是

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 升级的讨论,所以我们做补丁发布

第三方依赖升级说明如下

Third-party dependencies
Third-party dependencies

简单点来说就是:第三方依赖的补丁级别的修复,可以在 Spring Boot 的补丁版本中升级,而第三方依赖的次要或者主要版本的升级,则只能在 Spring Boot 的次要或主要版本中升级。不能在 Spring Boot 的补丁版本中升级第三方依赖的次要或者主要版本。这里的补丁版本可以理解成小版本,也就是 1.2.x 中的 x,而次要或者重要版本,则是 1.x.x 中的第一个 x,也就是我们所说的大版本

关于 scottfrederick,他可不是 Spring Boot 的普通 Contributor,人家可是榜六大哥

榜六
榜六

他说的还是很有权威的;关于他提到的讨论,我们后面在看,先把当前的看完。提问者 LSmyrnaios 又说了

LSmyrnaios 补充
LSmyrnaios 补充

翻译过来就是

scottfrederick,我们接着刚刚的讨论,我想问的是,是否有可能在 Spring Boot 的下一个大版本(比如 2.8.0,如果在计划中的话)将 SLF4J 升级到 2.0.x,logback 升级到 1.3.x 这对于大量的 Java 8 用户来说非常重要,他们希望为生产系统提供最新的安全和错误修复 先谢谢了

scottfrederick 说的就很符合我们的期望,我们接着往下看。wilkinsona 给出了回复

wilkinsona回复
wilkinsona回复

翻译过来就是

目前没有 Spring Boot 2.8 的计划

言简意赅,弦外之音就是 Spring Boot 2.x.x 就是不支持 Logback 1.3.x,满满的任性感。你们是不是很好奇这任性的哥们是谁?人家可是 Spring Boot 的榜一大哥!!!

榜一大哥
榜一大哥

是不是觉得他任性的理所当然了?我们继续往下看,ASarco 说了一句

ASarco
ASarco

翻译过来就是

现在的问题是 logback 1.2.12 存在安全漏洞 cve-2023-6378,对于 2.7.x 的煞笔用户却没有一个结论

这哥们表达了自己得愤懑,都直接飙国粹(SB)了,那是相当的气愤呀

SB 是 Spring Boot 的简写,并非国粹,大家别被误导了!!!

针对 ASarco 的问题,后面有人给了回复,可以升级 Logback1.2.13 来修复漏洞 cve-2023-6378,而我们也没得选了,只能将 Logback1.3.14 降到 1.2.13,最终的 pom.xml 如下所示

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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

StaticLoggerBinder移除记录
StaticLoggerBinder移除记录

1.3.0-alpha0 版本就移除了 StaticLoggerBinder,所以 Spring Boot 2.7.x 不能集成 Logback 1.3.x 的任何一个版本

2、snicoll (榜二大哥) 提到了一个很重要的点

snicoll_讨论
snicoll_讨论

Spring BootLoggingSystem 是可以禁用或者改变的

-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 通过读源代码,找到了一种解决方案

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@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,具体如何自定义,以及效果如何,且听下回分解

总结

  1. 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
  2. Spring Boot 官方也给出了答复,根据第三方依赖政策(小版本升级小版本,大版本升级大版本),2.7.x 不会支持 Logback 1.3.x,而 3.x.x 索性直接支持 Logback 1.4.x
  3. 非要 Spring Boot 2.7.x 支持 Logback 1.3.x 也不是不可以,需要调整配置,还存在一些限制,具体细节请看下篇
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-07-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴
SpringBoot2.7还是任性的,就是不支持Logback1.3,你能奈他何 讲了很多,总结下来就两点
青石路
2024/07/31
6160
SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴
结合实例看 maven 传递依赖与优先级,难顶也得上丫
此时你们是不是有疑问了:不就依赖 spring-boot-starter-web,怎么会有各种 log 的依赖?
青石路
2024/08/08
1430
结合实例看 maven 传递依赖与优先级,难顶也得上丫
Java日志体系框架总结:JUL、JCL、SLF4J、Log4j、Logback、Log4j2
日志记录是应用程序运行中必不可少的一部分。具有良好格式和完备信息的日志,可以在程序出现问题时帮助开发人员迅速地定位错误的根源。日志所能提供的功能是多种多样的,包括记录程序运行时产生的错误信息、状态信息、调试信息和执行时间信息等。
johnny666
2024/09/24
3160
springboot实战第四章-SpringMVC项目快速搭建
Spring MVC使我们可以简单地开发灵活且松耦合的Web项目,本章将关注基于注解和Java配置的Spring MVC开发。
全栈程序员站长
2021/05/19
8160
Spring Boot 2动态修改日志级别
作为程序猿,定位问题是我们的日常工作,而日志是我们定位问题非常重要的依据。传统方式定位问题时,往往是如下步骤:
张乘辉
2019/06/14
1.3K0
Spring Boot 2动态修改日志级别
从源码分析 SpringBoot 的 LoggingSystem → 它是如何绑定日志组件的
SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴 实现了 spring-boot 2.x.x 与 logback 1.3.x 的集成,分两步
青石路
2024/08/23
2190
从源码分析 SpringBoot 的 LoggingSystem → 它是如何绑定日志组件的
SLF4J2.0.x与Logback1.3.x的绑定变动还是很大的,不要乱点鸳鸯谱
在 SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴 原理分析那部分,我对 Logback 的表述是很委婉的
青石路
2024/08/03
3770
SLF4J2.0.x与Logback1.3.x的绑定变动还是很大的,不要乱点鸳鸯谱
13.7 SpringBoot集成日志系统logback的几个问题问题1: Logging system failed to initialize using configuration from
让人感到疑惑的是,SpringBoot居然没有对application.properties配置文件value末端作空格trim处理。
一个会写诗的程序员
2018/08/20
8.8K0
springboot linux启动报java.lang.IllegalArgumentException
本地开发环境idea启动项目正常,部署在linux服务器上面报上述jar包冲突,项目中用的是logback 日志,所以这里一定要排除slf4j-log4j12 包,不要排除logback-classic 包,通过idea maven项目管理可以看到jar包依赖关系
六月的雨在Tencent
2024/03/28
2070
springboot linux启动报java.lang.IllegalArgumentException
springboot第4集:springboot模块化开发与项目搭建流程
Spring Boot 是一个基于 Spring 框架的快速开发框架,可以用于构建独立的、生产级别的应用程序。在进行模块化开发时,将应用程序拆分为多个小的、可重用的模块,每个模块负责实现自己的功能。下面是 Spring Boot 模块化开发与项目搭建的流程:
达达前端
2023/10/08
9250
SpringBoot日志
工程结构: 默认使用logback日志 pom <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.o
HUC思梦
2020/09/03
3290
SpringBoot日志
JavaEE开发使用Maven管理的SpringMVC工程
前几篇博客已经陆陆续续的聊了一些Spring的东西,今天博客我们就来聊一下SpringMVC。SpringMVC目前在JavaEE开发中可谓占据一席之地,用起来也是比较顺手的。低耦合,高内聚,利用一些注解以及Java配置类就能很好的实现解耦。今天我们就来看一下如何使用Maven来配置SpringMVC, 然后在我们的Web工程中进行使用。 本篇博客是上一篇博客的续写,在上篇博客中我们详细的讲了Java环境的配置,Java EE版本的Eclipse的安装、Maven的安装与配置,Tomcat的安装与配置。并且
lizelu
2018/01/11
8740
JavaEE开发使用Maven管理的SpringMVC工程
快速了解常用日志技术(JCL、Slf4j、JUL、Log4j、Logback、Log4j2)
JUL全称Java util Logging是java原生的日志框架,使用时不需要另外引用第三方类库,相对其他日志框架使用方便,学习简单,能够在小型应用中灵活使用。
ha_lydms
2023/08/09
1.4K0
快速了解常用日志技术(JCL、Slf4j、JUL、Log4j、Logback、Log4j2)
SpringBoot启动报错:LoggerFactory is not a Logback LoggerContext but Logback is on the classpath
原文链接:https://blog.csdn.net/zhanggonglalala/article/details/88953345
chenchenchen
2019/09/02
64.3K1
SpringBoot启动报错:LoggerFactory is not a Logback LoggerContext but Logback is on the classpath
springboot-日志系统
JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j....
Java开发者之家
2021/06/17
8250
Spring Cloud 2.x系列之springcloud整合logback打印sql语句
Logback是由log4j创始人设计的又一个开源日志组件。logback当前分成三个模块:logback-core、logback- classic和logback-access。logback-core是其它两个模块的基础模块。logback-classic是log4j的一个 改良版本。此外logback-classic完整实现SLF4J API使你可以很方便地更换成其它日志系统如log4j或JDK14Logging。logback-access访问模块与Servlet容器集成提供通过Http来访问日志的功能。 Logback是要与SLF4J结合起来用的。
BUG弄潮儿
2022/06/30
7950
Spring Cloud 2.x系列之springcloud整合logback打印sql语句
SpringBoot之logback配置
日志对于应用程序来说是非常重要的,Spring框架本身集成了不少其他工具,我们自身的应用也会使用到第三方库,所以我们推荐在Spring应用中使用SLF4J/Logback来记录日志。
王念博客
2019/07/25
1.1K0
SpringBoot从1.5.4升级到2.7.2问题总结
编译不报错,启动报错,在springboot1.3版本中会默认提供一个RestTemplate的实例Bean,当在springboot1.4以及以后的版本中,需要手动创建一个RestTemplate的配置,这里将会导致循环依赖
猫头虎
2024/04/08
5600
SpringBoot从1.5.4升级到2.7.2问题总结
LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logba...
LoggerFactory is not a Logback LoggerContext but Logback is on the classpath. Either remove Logback or the competing implementation
一个会写诗的程序员
2018/08/17
1.9K0
【SpringMVC】SpringMVC基础-SpringMVC项目快速搭建、日志框架为logback
Spring MVC提供了一个DispatcherServlet来开发Web应用。
谙忆
2021/01/21
6070
【SpringMVC】SpringMVC基础-SpringMVC项目快速搭建、日志框架为logback
推荐阅读
相关推荐
SpringBoot2.7 霸王硬上弓 Logback1.3 → 不甜但解渴
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验