SLF4J-Warnung: Klassenpfad enthält mehrere SLF4J-Bindungen

1. Übersicht

Wenn wir SLF4J in unseren Anwendungen verwenden, wird manchmal eine Warnmeldung über mehrere Bindungen im auf der Konsole gedruckten Klassenpfad angezeigt.

In diesem Tutorial werden wir versuchen zu verstehen, warum diese Meldung angezeigt wird und wie sie behoben werden kann.

2. Die Warnung verstehen

Schauen wir uns zunächst eine Beispielwarnung an:

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 //www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]

Diese Warnung sagt uns, dass SLF4J zwei Bindungen gefunden hat. Einer ist in slf4j-log4j12-1.7.21.jar und der andere in logback-classic-1.1.7.jar .

Lassen Sie uns nun verstehen, warum wir diese Warnung sehen.

Die einfache Protokollierungsfassade für Java (SLF4J) dient als einfache Fassade oder Abstraktion für verschiedene Protokollierungsframeworks. Auf diese Weise können wir das gewünschte Protokollierungsframework zur Bereitstellungszeit anschließen.

Um dies zu erreichen, sucht SLF4J im Klassenpfad nach Bindungen (auch als Anbieter bezeichnet). Bindungen sind im Grunde Implementierungen einer bestimmten SLF4J-Klasse, die erweitert werden sollen, um ein bestimmtes Protokollierungsframework einzufügen.

SLF4J wird standardmäßig jeweils nur an ein Protokollierungsframework gebunden. Wenn mehr als eine Bindung im Klassenpfad vorhanden ist, wird folglich eine Warnung ausgegeben .

Es ist erwähnenswert, dass eingebettete Komponenten wie Bibliotheken oder Frameworks niemals eine Abhängigkeit von einer SLF4J-Bindung deklarieren sollten. Dies liegt daran, dass eine Bibliothek, wenn sie eine Abhängigkeit zur Kompilierungszeit von einer SLF4J-Bindung deklariert, diese Bindung dem Endbenutzer auferlegt. Dies negiert offensichtlich den Grundzweck von SLF4J. Folglich sollten sie nur von der slf4j-api- Bibliothek abhängen .

Es ist auch wichtig zu beachten, dass dies nur eine Warnung ist. Wenn SLF4J mehrere Bindungen findet, wählt es ein Protokollierungsframework aus der Liste aus und bindet daran. Wie in der letzten Zeile der Warnung zu sehen ist, hat SLF4J Log4j ausgewählt, indem org.slf4j.impl.Log4jLoggerFactory für die eigentliche Bindung verwendet wurde.

3. Finden der widersprüchlichen JARs

Die Warnung listet die Positionen aller gefundenen Bindungen auf. In der Regel sind dies ausreichende Informationen, um die skrupellose Abhängigkeit zu identifizieren, die eine unerwünschte SLF4J-Bindung transitiv in unser Projekt einbezieht.

Wenn es nicht möglich ist, die Abhängigkeit anhand der Warnung zu identifizieren, können wir die Abhängigkeit verwenden: tree maven target:

mvn dependency:tree

Dadurch wird der Abhängigkeitsbaum für das Projekt angezeigt:

[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 

Wir verwenden Logback zum Anmelden in unserer Anwendung. Daher haben wir bewusst die Logback-Bindung hinzugefügt, die in der Logback-klassischen JAR vorhanden ist. Die docx4j- Abhängigkeit hat jedoch auch eine andere Bindung mit der JAR slf4j-log4j12 hergestellt .

4. Auflösung

Nachdem wir die störende Abhängigkeit kennen, müssen wir nur noch die JAR slf4j-log4j12 von der docx4j- Abhängigkeit ausschließen:

 org.docx4j docx4j ${docx4j.version}   org.slf4j slf4j-log4j12   log4j log4j   

Da wir Log4j nicht verwenden werden, ist es möglicherweise eine gute Idee, es ebenfalls auszuschließen.

5. Schlussfolgerung

In diesem Artikel haben wir gesehen, wie wir die häufig auftretende Warnung vor mehreren von SLF4J ausgegebenen Bindungen beheben können.

Der diesem Artikel beiliegende Quellcode ist auf GitHub verfügbar.