Avviso SLF4J: il percorso classe contiene più bind SLF4J

1. Panoramica

Quando usiamo SLF4J nelle nostre applicazioni, a volte vediamo un messaggio di avviso su più associazioni nel classpath stampato sulla console.

In questo tutorial, proveremo a capire perché vediamo questo messaggio e come risolverlo.

2. Capire l'avvertimento

Per prima cosa, diamo un'occhiata a un avviso di esempio:

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]

Questo avviso ci sta dicendo che SLF4J ha trovato due associazioni. Uno è in slf4j-log4j12-1.7.21.jar e l'altro in logback-classic-1.1.7.jar .

Ora capiamo perché vediamo questo avviso.

La Simple Logging Facade for Java (SLF4J) funge da semplice facciata o astrazione per vari framework di registrazione. Pertanto, ci consente di collegare il nostro framework di registrazione desiderato al momento della distribuzione.

Per ottenere ciò, SLF4J cerca i collegamenti (noti anche come provider) sul classpath. I binding sono fondamentalmente implementazioni di una particolare classe SLF4J destinata ad essere estesa per collegare uno specifico framework di registrazione.

Per impostazione predefinita, SLF4J si collegherà solo con un framework di registrazione alla volta. Di conseguenza, se più di un binding è presente sul classpath, verrà emesso un avviso .

Vale la pena notare che i componenti incorporati come librerie o framework non dovrebbero mai dichiarare una dipendenza da alcun binding SLF4J. Questo perché quando una libreria dichiara una dipendenza in fase di compilazione su un'associazione SLF4J, impone tale associazione all'utente finale. Ovviamente, questo nega lo scopo fondamentale di SLF4J. Di conseguenza, dovrebbero dipendere solo dalla libreria slf4j-api .

È anche importante notare che questo è solo un avvertimento. Se SLF4J trova più collegamenti, selezionerà un framework di registrazione dall'elenco e si collegherà con esso. Come si può vedere nell'ultima riga dell'avviso, SLF4J ha scelto Log4j utilizzando org.slf4j.impl.Log4jLoggerFactory per l'associazione effettiva.

3. Trovare i JAR in conflitto

L'avviso elenca le posizioni di tutte le associazioni che trova. Di solito, questa è un'informazione sufficiente per identificare la dipendenza senza scrupoli che trascina transitivamente un binding SLF4J indesiderato nel nostro progetto.

Se non è possibile identificare la dipendenza dall'avviso, possiamo utilizzare la dipendenza: tree maven goal:

mvn dependency:tree

Questo mostrerà l'albero delle dipendenze per il progetto:

[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 

Stiamo utilizzando Logback per accedere alla nostra applicazione. Pertanto, abbiamo aggiunto deliberatamente l'associazione Logback, presente nel JAR classico di logback . Ma la dipendenza docx4j ha anche inserito un altro collegamento con il JAR slf4j-log4j12 .

4. Risoluzione

Ora che conosciamo la dipendenza incriminata, tutto ciò che dobbiamo fare è escludere il JAR slf4j-log4j12 dalla dipendenza docx4j :

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

Dato che non useremo Log4j, potrebbe essere una buona idea escluderlo.

5. conclusione

In questo articolo, abbiamo visto come possiamo risolvere l'avvertimento visto di frequente su più associazioni emesse da SLF4J.

Il codice sorgente che accompagna questo articolo è disponibile su GitHub.