# 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

When running, we can see that an additional LoggingSystem Factory implementation has been added,
with Slf4j2LogbackLoggingSystem ranked first:

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
```