Skip to content

Commons-Logging Conflict in Spring Boot Applications

Problem Statement

When using Spring Boot 3.x, you may encounter the following warning message during application startup:

text
Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts

This warning indicates that both Spring's spring-jcl (Jakarta Commons Logging bridge) and the legacy Apache Commons Logging (commons-logging) library are present in your classpath. Spring Boot includes spring-jcl automatically as part of its logging infrastructure, which provides modern logging capabilities.

The conflict occurs when:

  • Your application has indirect dependencies on commons-logging (usually through other libraries)
  • The coexistence of both logging implementations can cause unpredictable runtime behavior
  • Logging configurations might not work as expected
  • Performance issues may occur due to classloader scanning operations

Solution

The recommended solution is to exclude the commons-logging dependency from your project's dependencies while retaining spring-jcl. Below are implementation approaches for different build systems.

Maven Configuration

Modify your pom.xml to exclude commons-logging from the problematic dependency:

xml
<dependency>
    <groupId>com.mashape.unirest</groupId>
    <artifactId>unirest-java</artifactId>
    <version>1.4.9</version>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

Gradle Configuration (Groovy DSL)

For build.gradle:

groovy
implementation('com.mashape.unirest:unirest-java:1.4.9') {
    exclude group: 'commons-logging', module: 'commons-logging'
}

Gradle Configuration (Kotlin DSL)

For build.gradle.kts:

kotlin
implementation("com.mashape.unirest:unirest-java:1.4.9") {
    exclude(group = "commons-logging", module = "commons-logging")
}

Method 2: Global Exclusion (Use with Caution)

If multiple dependencies require exclusion, use these configurations:

Maven Global Exclusion

Add this to your pom.xml:

xml
<dependencies>
    <!-- Your dependencies -->
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>3.4.0</version>
            <configuration>
                <packagingExcludes>
                    **/commons-logging/*
                </packagingExcludes>
            </configuration>
        </plugin>
    </plugins>
</build>

Gradle Global Exclusion

For build.gradle.kts:

kotlin
configurations.all {
    exclude(group = "commons-logging", module = "commons-logging")
}

For Groovy DSL (build.gradle):

groovy
configurations {
    all {
        exclude group: 'commons-logging', module: 'commons-logging'
    }
}

WARNING

Use global exclusions sparingly as they might accidentally exclude required logging dependencies from other libraries. Always verify with mvn dependency:tree (Maven) or gradle dependencies (Gradle) afterwards.

Verification

After applying the exclusion, verify that commons-logging is no longer present in your dependencies:

Maven

bash
mvn dependency:tree | grep commons-logging

Gradle

bash
gradle dependencies | grep commons-logging

Why This Solution Works

Spring Boot uses the spring-jcl module as its default logging facade, with these benefits:

  1. Bridge Architecture: Redirects logging calls to your preferred logging implementation (Logback, Log4j2, etc.)
  2. Optimized Performance: Avoids expensive runtime scanning used by commons-logging
  3. Modern Integration: Designed for seamless Spring Boot auto-configuration
  4. Conflict Prevention: Eliminates dual-binding issues in logging frameworks

TIP

If you see the warning with multiple dependencies, use Method 2 temporarily, then gradually replace with targeted exclusions (Method 1) for better maintainability.

Additional Tips

  1. Check Transitive Dependencies: Always analyze your dependencies with:
    bash
    # Maven
    mvn dependency:tree
    
    # Gradle
    gradle dependencies
  2. Spring Boot 3+ Compatibility: Ensure all dependencies are compatible with Spring Boot 3.x and Jakarta EE 9+
  3. Logging Bridge Health: Confirm your logging implementation shows initialization messages at startup without warnings

Alternative: Explicit Dependency Declaration (Fallback)

If exclusion doesn't resolve the issue, explicitly declare spring-jcl:

xml
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jcl</artifactId>
    <version>6.0.10</version> <!-- Match your Spring Boot version -->
</dependency>

However, this is rarely necessary in Spring Boot projects as spring-jcl is already included transitively.