Skip to content

commons-logging と spring-jcl の競合解決

問題の概要

Spring Boot アプリケーションで次の警告メッセージが表示される場合があります。

log
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 をロギング実装として使用しますが、以下の点で問題が発生します。

  1. 他の依存関係(unirest-java)が commons-logging を推移的に取り込む
  2. 両ライブラリが同じロギングインターフェースを実装しようとする
  3. クラスローダーがどちらを使用するべきか判断できなくなる

依存関係ツリーを見ると問題の根本が明確にわかります:

[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.xmlunirest-java 依存関係から commons-logging を除外します:

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プロジェクトの場合

build.gradle に次の除外設定を追加します:

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

代替ソリューション

グローバルな除外設定 (Gradle)

特定の依存関係ではなく、プロジェクト全体から除去する方法:

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

別の依存関係から除外する場合

例えば Spring Cloud Eureka から除外する場合:

xml
<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 を完全に置き換えることができます。除外することで:

  1. 不要なライブラリが削除されアプリケーションサイズが減少
  2. ロギングフレームワークの一貫性が保たれる
  3. 潜在的なクラスローダーの競合が解消
  4. Spring Bootのロギング自動設定が正しく機能

検証手順

解決後、次のコマンドを実行して commons-logging が完全に排除されたことを確認してください。

Mavenの場合:

bash
mvn dependency:tree | grep commons-logging

Gradleの場合:

bash
gradle dependencies | grep commons-logging

これらのコマンドで何も出力されなければ、問題は解決しています。

補足事項

  • commons-logging を除外してもほとんどの場合アプリケーション機能に影響なし
  • 複数の依存関係が commons-logging を参照する場合、各依存に対して除外設定が必要
  • この問題は unirest-java 以外のライブラリを使用した場合にも発生可能性あり

警告メッセージが表示されなくなれば、競合は解決されています。これにより Spring Boot のロギングシステムが適切に機能するようになります。