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:
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.
Method 1: Exclude from Specific Dependency (Recommended)
Maven Configuration
Modify your pom.xml
to exclude commons-logging
from the problematic dependency:
<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
:
implementation('com.mashape.unirest:unirest-java:1.4.9') {
exclude group: 'commons-logging', module: 'commons-logging'
}
Gradle Configuration (Kotlin DSL)
For build.gradle.kts
:
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
:
<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
:
configurations.all {
exclude(group = "commons-logging", module = "commons-logging")
}
For Groovy DSL (build.gradle
):
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
mvn dependency:tree | grep commons-logging
Gradle
gradle dependencies | grep commons-logging
Why This Solution Works
Spring Boot uses the spring-jcl
module as its default logging facade, with these benefits:
- Bridge Architecture: Redirects logging calls to your preferred logging implementation (Logback, Log4j2, etc.)
- Optimized Performance: Avoids expensive runtime scanning used by commons-logging
- Modern Integration: Designed for seamless Spring Boot auto-configuration
- 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
- Check Transitive Dependencies: Always analyze your dependencies with:bash
# Maven mvn dependency:tree # Gradle gradle dependencies
- Spring Boot 3+ Compatibility: Ensure all dependencies are compatible with Spring Boot 3.x and Jakarta EE 9+
- 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
:
<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.