SLF4J警告:クラスパスに複数のSLF4Jバインディングが含まれています

1. 概要

アプリケーションでSLF4Jを使用すると、コンソールに出力されるクラスパス内の複数のバインディングに関する警告メッセージが表示されることがあります。
このチュートリアルでは、このメッセージが表示される理由と解決方法を理解しようとします。

2. 警告を理解する

まず、サンプルの警告を見てみましょう。
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:.../slf4j-log4j12-1.7.21.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:.../logback-classic-1.1.7.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
この警告は、SLF4Jが2つのバインディングを見つけたことを示しています。 1つは_slf4j-log4j12-1.7.21.jar_にあり、もう1つは_logback-classic-1.1.7.jar_にあります。
次に、この警告が表示される理由を理解しましょう。
link:/slf4j-with-log4j2-logback[Simple Logging Facade for Java(SLF4J)]は、さまざまなlink:/java-loggingの単純なファサードまたは抽象化として機能します。 -intro [ロギング]フレームワーク。 したがって、デプロイ時に目的のロギングフレームワークをプラグインできます。
これを実現するために、SLF4Jはクラスパスでバインディング(別名プロバイダー)を探します。 バインディングは基本的に、特定のロギングフレームワークをプラグインするために拡張されることを意図した特定のSLF4Jクラスの実装です。
設計上、SLF4Jは一度に1つのロギングフレームワークのみにバインドします。 そのため、*クラスパスに複数のバインディングが存在する場合、警告が発せられます*。
ライブラリやフレームワークなどの組み込みコンポーネントは、SLF4Jバインディングへの依存関係を宣言しないでください。 これは、ライブラリがSLF4Jバインディングでコンパイル時の依存関係を宣言するとき、エンドユーザーにそのバインディングを課すためです。 明らかに、これはSLF4Jの基本的な目的を無効にします。 したがって、これらは_slf4j-api_ library __.__のみに依存する必要があります。
*これは単なる警告であることに注意することも重要です。* SLF4Jが複数のバインディングを検出した場合、リストから1つのロギングフレームワークを選択してバインドします。 警告の最後の行に見られるように、SLF4Jは実際のバインディングに_org.slf4j.impl.Log4jLoggerFactory_を使用してLog4jを選択しています。

3. 競合するJARを見つける

警告には、検出されたすべてのバインディングの場所がリストされます。 通常、これは、プロジェクトに望ましくないSLF4Jバインディングを一時的に取り込む不un慎な依存関係を識別するのに十分な情報です。
警告から依存関係を特定できない場合は、_dependency:tree_ mavenゴールを使用できます。
mvn dependency:tree
これにより、プロジェクトの依存関係ツリーが表示されます。
[INFO] +- org.docx4j:docx4j:jar:3.3.5:compile
[INFO] |  +- org.slf4j:slf4j-log4j12:jar:1.7.21:compile
[INFO] |  +- log4j:log4j:jar:1.2.17:compile
[INFO] +- ch.qos.logback:logback-classic:jar:1.1.7:compile
[INFO] +- ch.qos.logback:logback-core:jar:1.1.7:compile
アプリケーションのログインにLogbackを使用しています。 したがって、意図的に_logback-classic_ JARに存在するLogbackバインディングを追加しました。 しかし、_docx4j_依存関係は、_slf4j-log4j12_ JARとの別のバインディングも引き込みました。

4. 解決

問題のある依存関係がわかったので、_docx4j_依存関係から_slf4j-log4j12_ JARを除外するだけです。
<dependency>
    <groupId>org.docx4j</groupId>
    <artifactId>docx4j</artifactId>
    <version>${docx4j.version}</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>
Log4jは使用しないので、Log4jも除外することをお勧めします。

5. 結論

この記事では、SLF4Jによって発行された複数のバインディングに関するよくある警告を解決する方法を説明しました。
この記事に付属するソースコードはhttps://github.com/eugenp/tutorials/tree/master/logging-modules/logback[over on GitHub]で入手できます。