commons-logging と spring-jcl の競合解決
問題の概要
Spring Boot アプリケーションで次の警告メッセージが表示される場合があります。
Standard Commons Logging discovery in action with spring-jcl: please remove commons-logging.jar from classpath in order to avoid potential conflicts
この警告は、Apache Commons Logging (commons-logging
) ライブラリと Spring Java Commons Logging (spring-jcl
) ライブラリがクラスパス上で衝突している状態を示しています。
問題の原因分析
Spring Boot はデフォルトで spring-jcl
をロギング実装として使用しますが、以下の点で問題が発生します。
- 他の依存関係(
unirest-java
)がcommons-logging
を推移的に取り込む - 両ライブラリが同じロギングインターフェースを実装しようとする
- クラスローダーがどちらを使用するべきか判断できなくなる
依存関係ツリーを見ると問題の根本が明確にわかります:
[INFO] +- com.mashape.unirest:unirest-java:jar:1.4.9:compile
[INFO] | +- org.apache.httpcomponents:httpclient:jar:4.5.2:compile
[INFO] | | +- commons-logging:commons-logging:jar:1.2:compile <-- 問題の原因
解決方法
Mavenプロジェクトの場合
pom.xml
で unirest-java
依存関係から commons-logging
を除外します:
<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プロジェクトの場合
build.gradle
に次の除外設定を追加します:
implementation('com.mashape.unirest:unirest-java:1.4.9') {
exclude group: 'commons-logging', module: 'commons-logging'
}
代替ソリューション
グローバルな除外設定 (Gradle)
特定の依存関係ではなく、プロジェクト全体から除去する方法:
configurations.all {
exclude group: 'commons-logging', module: 'commons-logging'
}
別の依存関係から除外する場合
例えば Spring Cloud Eureka から除外する場合:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
なぜこの解決策か
spring-jcl
は Spring Framework に最適化されたロギング実装であり、commons-logging
を完全に置き換えることができます。除外することで:
- 不要なライブラリが削除されアプリケーションサイズが減少
- ロギングフレームワークの一貫性が保たれる
- 潜在的なクラスローダーの競合が解消
- Spring Bootのロギング自動設定が正しく機能
検証手順
解決後、次のコマンドを実行して commons-logging
が完全に排除されたことを確認してください。
Mavenの場合:
mvn dependency:tree | grep commons-logging
Gradleの場合:
gradle dependencies | grep commons-logging
これらのコマンドで何も出力されなければ、問題は解決しています。
補足事項
commons-logging
を除外してもほとんどの場合アプリケーション機能に影響なし- 複数の依存関係が
commons-logging
を参照する場合、各依存に対して除外設定が必要 - この問題は
unirest-java
以外のライブラリを使用した場合にも発生可能性あり
警告メッセージが表示されなくなれば、競合は解決されています。これにより Spring Boot のロギングシステムが適切に機能するようになります。