Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade to SLF4J 2.0 and Logback 1.4 #12649

Closed
wilkinsona opened this issue Mar 27, 2018 · 74 comments
Closed

Upgrade to SLF4J 2.0 and Logback 1.4 #12649

wilkinsona opened this issue Mar 27, 2018 · 74 comments
Assignees
Labels
type: dependency-upgrade A dependency upgrade
Milestone

Comments

@wilkinsona
Copy link
Member

With thanks to @rwinch, I've just learned that Boot doesn't work with Logback 1.3 (still in alpha). It fails on launch with the following exception:

java.lang.NoClassDefFoundError: org/slf4j/impl/StaticLoggerBinder
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.getLoggerContext(LogbackLoggingSystem.java:273)
    at org.springframework.boot.logging.logback.LogbackLoggingSystem.beforeInitialize(LogbackLoggingSystem.java:99)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationStartingEvent(LoggingApplicationListener.java:191)
    at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:170)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127)
    at org.springframework.boot.context.event.EventPublishingRunListener.starting(EventPublishingRunListener.java:68)
    at org.springframework.boot.SpringApplicationRunListeners.starting(SpringApplicationRunListeners.java:48)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:313)

StaticLoggerBinder was removed in this commit which appears to be part of a broader effort to provide Jigsaw modules for SLF4J and Logback.

@wilkinsona wilkinsona added the type: enhancement A general enhancement label Mar 27, 2018
@wilkinsona wilkinsona added this to the Backlog milestone Mar 27, 2018
@wilkinsona wilkinsona added the status: blocked An issue that's blocked on an external project change label Jun 1, 2018
@philwebb
Copy link
Member

Logback 1.3 is still in alpha so I think we should push this back to Spring Boot 2.2

@philwebb philwebb modified the milestones: 2.1.x, 2.x Sep 11, 2018
@aprantl
Copy link

aprantl commented Dec 17, 2018

Apparently the extension module of SLF4J prior to 1.8.0-beta2 contains a security vulnerability (see https://nvd.nist.gov/vuln/detail/CVE-2018-8088#VulnChangeHistorySection). As such, I wouldn't consider this ticket just an enhancement anymore. What do you think?

@snicoll
Copy link
Member

snicoll commented Dec 17, 2018

@aprantl slf4j-ext and slf4j-api are separate modules and Spring Boot itself does not depend on the module that holds the vulnerability. An application that only depends on slf4j-api is not at risk.

@aprantl
Copy link

aprantl commented Dec 17, 2018

@snicoll Thanks for the quick reply. What would you recommend if an application based on Spring Boot relies on the extension module in its custom code? I guess the ext-module cannot be updated to 1.8.0-beta2 without dependency-managing the entire SLF4J and logback framework. Which again would not be possible considering the issue above.

@wilkinsona
Copy link
Member Author

If you're not using EventData then my understanding is that you're not vulnerable even if you have slf4j-ext on the classpath. You should confirm that with the SLF4J team though.

@jhigueras

This comment has been minimized.

@snicoll

This comment has been minimized.

@wilkinsona

This comment has been minimized.

@jhigueras

This comment has been minimized.

@cowwoc

This comment has been minimized.

@wilkinsona

This comment has been minimized.

@cowwoc

This comment has been minimized.

@wilkinsona

This comment has been minimized.

@cowwoc

This comment has been minimized.

@philwebb

This comment has been minimized.

@cowwoc

This comment has been minimized.

@philwebb

This comment has been minimized.

@hohwille
Copy link

I am facing the same problem in my OSS project that I migrated to JPMS entirely.
The problem ist that there seems no way to make it work with spring-boot currently.
I can not even disable LogbackLoggingSystem and make spring-boot log to jul instead. It seems to be hardwired inside spring-boot that if logback is found on the classpath that StaticLoggerBinder is loaded what has been removed from logback.
I can imagine that it is really tricky to support all this messy variants with Junit4 vs. 5, classpath vs. modulepath, etc. Some OSS projects IMHO seem to tend making breaking changes without considering impact vs. benefit (e.g. junit, spring-data, etc.).

@snicoll
Copy link
Member

snicoll commented May 10, 2020

I can not even disable LogbackLoggingSystem

Disabling or changing the LoggingSystem that Spring Boot uses is possible and documented in the reference guide.

@hohwille
Copy link

Disabling or changing the LoggingSystem that Spring Boot uses is possible and documented in the reference guide.

Thanks for the hint. Indeed it works when I launch my test with

-Dorg.springframework.boot.logging.LoggingSystem=none

and I still get the log output.

However, I need the test to be portable, run by anybody in maven, any IDE, etc.
I tried this:

@SpringBootTest(classes = TestApp.class, properties = "org.springframework.boot.logging.LoggingSystem=none", webEnvironment = WebEnvironment.RANDOM_PORT)

But it has to be set as a system property in the boostrapping.

@wilkinsona
Copy link
Member Author

If you know that users of your project will never want to use Spring Boot's logging system, you can use an ApplicationListener, registered in spring.factories and with higher precedence than org.springframework.boot.context.logging.LoggingApplicationListener, to set the system property in response to an ApplicationStartingEvent.

@skjolber
Copy link

As a side note: The SLF4J 1.8 beta seems to work with Logback 1.2.3, if you return StaticLoggerBinder.getSingleton().getLoggerFactory() in your custom SLF4JServiceProvider getLoggerFactory(..) method.

@wilkinsona wilkinsona changed the title Support SLF4J 1.8 and Logback 1.3 Support SLF4J 2.0 and Logback 1.3 Jan 24, 2022
@wilkinsona
Copy link
Member Author

This has become more important for Spring Boot 3.0 and applications using an SMTP appender. In Logback 1.2, the SMTP appender uses javax.mail classes from Java EE 8. The Logback 1.3 alphas have moved to the jakarta.mail classes that are compatible with Jakarta EE 9.

@code-magician323
Copy link

code-magician323 commented Sep 23, 2022

@wilkinsona Will this get merged until Spring Boot 3.0.0?

@wilkinsona
Copy link
Member Author

@code-magician323 As I said above, the current target is 3.0.0-RC1.

@wilkinsona wilkinsona modified the milestones: 3.x, 3.0.x Sep 26, 2022
@wilkinsona wilkinsona added type: dependency-upgrade A dependency upgrade and removed type: enhancement A general enhancement labels Sep 27, 2022
@wilkinsona wilkinsona modified the milestones: 3.0.x, 3.0.0-RC1 Sep 28, 2022
@zyxist
Copy link

zyxist commented Oct 6, 2022

It's possible to make Spring Boot 2.x work with Slf4j 2.0 simply by disabling the custom logging facade used by Spring Boot. To do so, one needs to set org.springframework.boot.logging.LoggingSystem system property to none (and also making sure that all dependencies to logback/slf4j on classpath have been updated in Maven/Gradle). I managed to run my project in this way.

As I looked at the code, it should be possible to write a custom LoggingSystemFactory for Spring Boot that delegates stuff to Slf4j, rather than talking to Logback directly. The public API of Slf4j 2.0.x is backward compatible with 1.x. In fact, I wished if things were done in this way from the beginning.

wilkinsona added a commit that referenced this issue Oct 13, 2022
The module was removing in SLF4J 2.0

See gh-12649
@prbbj
Copy link

prbbj commented Dec 12, 2022

set org.springframework.boot.logging.LoggingSystem system property to none

How to do this in Intellij?

@h2nguyen
Copy link

set org.springframework.boot.logging.LoggingSystem system property to none
How to do this in Intellij?

this can be done within the pom.xml file, just look for the maven-surefire-plugin e.g.:

...
<plugins>
   ...
   <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.0.0-M5</version>
                <configuration>
                    ...
                    <systemPropertyVariables>
                        <org.springframework.boot.logging.LoggingSystem>none</org.springframework.boot.logging.LoggingSystem>
                    </systemPropertyVariables>
                    ...
                </configuration>
            </plugin>
   ...
</plugins>
...

@zhaolj214
Copy link

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>2.0.5</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.version}</version>
</dependency>
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-core</artifactId>
    <version>1.3.7</version>
</dependency>

after reading the source code, add the following code to the startup class, then launch without exception.

@SpringBootApplication
public class Spring5Application {
    public static void main(String[] args) {
        System.setProperty("org.springframework.boot.logging.LoggingSystem", "none");
        SpringApplication.run(Spring5Application.class, args);
    }
}

@adamk33n3r
Copy link

after reading the source code, add the following code to the startup class, then launch without exception.

@SpringBootApplication
public class Spring5Application {
    public static void main(String[] args) {
        System.setProperty("org.springframework.boot.logging.LoggingSystem", "none");
        SpringApplication.run(Spring5Application.class, args);
    }
}

this does let me boot, but wow the output log is insanely verbose now. and colorless.

@wilkinsona
Copy link
Member Author

wilkinsona commented May 1, 2024

That's Logback's default configuration. You can customize it, perhaps using Boot's configuration as a starting point. Note that the file must be logback.xml and not logback-spring.xml when you've set the logging system to none.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: dependency-upgrade A dependency upgrade
Projects
None yet
Development

No branches or pull requests