Resolving Logger Conflicts in Spring Boot: LoggerFactory is not a Logback LoggerContext but Logback is on the Classpath

Nov 26, 2025 · Programming · 9 views · 7.8

Keywords: Spring Boot | Logging Conflicts | Logback | Log4j2 | Dependency Exclusion | Gradle Configuration

Abstract: This article addresses the common logging framework conflict issue in Spring Boot projects where LoggerFactory is not a Logback LoggerContext but Logback is present on the classpath. Through analysis of the logging module conflict mechanism in Spring Boot Starter dependencies, it provides detailed explanations of compatibility issues between Logback and Log4j2. The article offers comprehensive solutions based on Gradle dependency exclusion, including precise exclusion configurations for spring-boot-starter-security and spring-boot-starter-thymeleaf modules, supplemented with recommendations for using dependency tree analysis tools. Finally, code examples demonstrate how to properly configure Log4j2 as the project's logging implementation framework.

Problem Background and Cause Analysis

During Spring Boot application development, logging framework conflicts frequently occur, especially when multiple logging implementations coexist in the project. The typical error message shows: LoggerFactory is not a Logback LoggerContext but Logback is on the classpath, indicating that multiple competing logging implementations have been detected in the system.

Spring Boot uses Logback as the default logging implementation, but many projects choose to use Log4j2 due to performance or functional requirements. When both Logback and Log4j2 are introduced in a project, SLF4J as the logging facade cannot determine which specific logging implementation to use, resulting in conflicts.

Root Cause of Dependency Conflicts

Spring Boot Starter dependencies typically include spring-boot-starter-logging, which by default introduces Logback as the logging implementation. Even if this module is excluded in some Starters, other Starters may still indirectly introduce Logback-related dependencies.

Taking the Gradle configuration from the problem as an example:

compile("org.springframework.boot:spring-boot-starter-thymeleaf")
compile("org.springframework.boot:spring-boot-starter-security"){
    exclude module: "spring-boot-starter-logging"
}
compile "org.apache.logging.log4j:log4j-api"
compile "org.apache.logging.log4j:log4j-core"
compile "org.apache.logging.log4j:log4j-slf4j-impl"

Although spring-boot-starter-logging has been excluded from spring-boot-starter-security, spring-boot-starter-thymeleaf may still introduce Logback through transitive dependencies.

Solution Implementation

Based on best practices, we need to perform precise exclusions in all Starter dependencies that may introduce Logback:

compile("org.springframework.boot:spring-boot-starter-security"){
    exclude module: "spring-boot-starter-logging"
    exclude module: "logback-classic"
}
compile("org.springframework.boot:spring-boot-starter-thymeleaf"){
    exclude module: "logback-classic"
}

This configuration ensures:

Using Dependency Analysis Tools

To ensure all Logback dependencies are properly excluded, it's recommended to use dependency analysis tools:

In Gradle, you can use:

./gradlew dependencies

Or in Maven:

mvn dependency:tree -Dverbose

These commands help identify all transitive dependencies that introduce Logback, enabling precise exclusions.

Log4j2 Configuration Example

After successfully excluding Logback dependencies, proper configuration of Log4j2 is required. Here's a basic log4j2.xml configuration example:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
        </Root>
    </Loggers>
</Configuration>

Verification and Testing

After configuration, you can verify if the logging framework is working properly with simple test code:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogTest {
    private static final Logger logger = LoggerFactory.getLogger(LogTest.class);
    
    public void testLogging() {
        logger.info("This is a test log message using Log4j2");
    }
}

If the console correctly outputs log messages without conflict errors, the configuration is successful.

Summary and Best Practices

The key to resolving logging framework conflicts in Spring Boot includes:

By following these best practices, you can effectively avoid logging conflict issues like LoggerFactory is not a Logback LoggerContext and ensure stable project operation.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.