# spring-boot-sfj4j2 **Repository Path**: qdbp/spring-boot-sfj4j2 ## Basic Information - **Project Name**: spring-boot-sfj4j2 - **Description**: 解决在spring-boot-2.x中升级slf4j至2.x时出现的报错问题 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2025-08-15 - **Last Updated**: 2026-06-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # spring-boot-sfj4j2 #### Introduction Solve the error problem that occurs when upgrading slf4j to 2.x in the spring-boot-2.x #### Problem Cause We have a legacy project using spring-boot-2.7.18.
Recently, a vulnerability scan revealed issues with logback.
The project was using logback 1.2.x,
and even after upgrading to the latest version (as of August 2025) 1.2.13,
there are still 3 medium-risk vulnerabilities reported.
To upgrade further, we need to simultaneously upgrade slf4j to 2.x.
After making these changes and starting the project,
we encountered this error: ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder
The reason is that slf4j changed its logger instance discovery mechanism from
the previous static binding mechanism to the SPI mechanism.
However, the LogbackLoggingSystem in spring-boot-2.7.x uses the old class,
resulting in the error: ``` log 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.base/java.util.ArrayList.forEach(ArrayList.java:1511) 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.gitee.qdbp.slf4j2.test.Application.main(Application.java:26) Caused by: java.lang.ClassNotFoundException: org.slf4j.impl.StaticLoggerBinder at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ... 17 more ``` #### Problem Analysis The main role of LoggingSystem in Spring Boot is to support variable reading in logback.xml: ``` xml ...... ${LOG_HOME}/${appName}.log ...... ``` Online solutions suggest disabling LoggingSystem, which allows the project to start.
but then the above variables cannot be read,
and logback-spring.xml needs to be renamed to logback.xml ``` java System.setProperty("org.springframework.boot.logging.LoggingSystem", "none"); SpringApplication.run(Application.class, args); ``` After reviewing the source code of spring-boot's LoggingSystem,
we found that we can implement a custom LogbackLoggingSystem.
By adding a LoggingSystem Factory through META-INF/spring.factories,
we can modify the underlying implementation.
By comparing the different implementations of
LogbackLoggingSystem in versions 2.7.18 and 3.5.4,
we can basically migrate the logic from 3.5.4. #### Code Implementation Call Relationship Diagram ![调用关系图](https://foruda.gitee.com/images/1755183992405025114/c4048460_610326.png "调用关系图") When running, we can see that an additional LoggingSystem Factory implementation has been added,
with Slf4j2LogbackLoggingSystem ranked first: ![工厂类实例](https://foruda.gitee.com/images/1755181430686892162/7cca967a_610326.png "工厂类实例") The key entry point is here: ``` java @Order(Ordered.LOWEST_PRECEDENCE - 10000) // 提高优先级 public static class Factory implements LoggingSystemFactory { // 有LoggerContext且没有StaticLoggerBinder才生效 private static final boolean PRESENT = ClassUtils.isPresent("ch.qos.logback.classic.LoggerContext", Factory.class.getClassLoader()) && !ClassUtils.isPresent("org.slf4j.impl.StaticLoggerBinder", Factory.class.getClassLoader()); @Override public LoggingSystem getLoggingSystem(ClassLoader classLoader) { if (PRESENT) { return new Slf4j2LogbackLoggingSystem(classLoader); } return null; } } ``` #### Log Testing The main test is to verify that the project starts normally after adding the spring-boot-sfj4j2 dependency,
without the error: `NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder.`
Additionally, test that the appName variable in logback-spring.xml is successfully retrieved:
`${LOG_HOME}/${appName}.log`
In the test project: spring-boot-sfj4j2-test-logback
after successful startup, there should be a slf4j2-test-logback.logfile in the logs directory. #### Maven Dependency [https://repo1.maven.org/maven2/com/gitee/qdbp/spring-boot-sfj4j2/2.7.18/](https://repo1.maven.org/maven2/com/gitee/qdbp/spring-boot-sfj4j2/2.7.18/) ``` xml com.gitee.qdbp spring-boot-sfj4j2 2.7.18 ```