Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to suppress SLF4J Warning about multiple bindings?

My java project has dependencies with different SLF4J versions. How do I suppress the annoying warnings?

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:xyz234/lib/slf4j-
log4j12-1.5.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]

SLF4J: Found binding in [jar:file:xyz123/.m2/repository/org/slf4j/slf4j-log4j12
/1.6.0/slf4j-log4j12-1.6.0.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.

P.S.: This is not the same question as slf4j warning about the same binding being duplicate, the answer there is how to get rid of a false alarm warning, in my case it is a true warning however. P.S.S.: Sorry, I forgot to mention: I use Maven and SLF4J is included in the dependencies of my dependencies.

like image 801
Konrad Höffner Avatar asked Sep 27 '11 15:09

Konrad Höffner


People also ask

How to suppress SLF4J warning?

since 1.6. 0 As of SLF4J version 1.6, in the absence of a binding, SLF4J will default to a no-operation (NOP) logger implementation. If you are responsible for packaging an application and do not care about logging, then placing slf4j-nop. jar on the class path of your application will get rid of this warning message.

What is SLF4J bindings?

Bindings are basically implementations of a particular SLF4J class meant to be extended to plug in a specific logging framework. By design, SLF4J will only bind with one logging framework at a time. Consequently, if more than one binding is present on the classpath, it will emit a warning.

What is SLF4J reload4j?

2022-03-17 - Release of SLF4J 2.0. The reload4j project is a fork of Apache log4j version 1.2. 17 with the goal of fixing pressing security issues. It is intended as a drop-in replacement for log4j version 1.2. 17. By drop-in, we mean the replacement of log4j.


1 Answers

Remove one of the slf4j-log4j12-1.5.8.jar or slf4j-log4j12-1.6.0.jar from the classpath. Your project should not depend on different versions of SLF4J. I suggest you to use just the 1.6.0.

If you're using Maven, you can exclude transitive dependencies. Here is an example:

<dependency>
    <groupId>com.sun.xml.stream</groupId>
    <artifactId>sjsxp</artifactId>
    <version>1.0.1</version>
    <exclusions>
        <exclusion>
            <groupId>javax.xml.stream</groupId>
            <artifactId>stax-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

With the current slf4j-api implementation it is not possible to remove these warnings. The org.slf4j.LoggerFactory class prints the messages:

  ...
  if (implementationSet.size() > 1) {
    Util.report("Class path contains multiple SLF4J bindings.");
    Iterator iterator = implementationSet.iterator();
    while(iterator.hasNext()) {
      URL path = (URL) iterator.next();
      Util.report("Found binding in [" + path + "]");
    }
    Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
  }
  ...

The Util class is the following:

public class Util {

  static final public void report(String msg, Throwable t) {
    System.err.println(msg);
    System.err.println("Reported exception:");
    t.printStackTrace();
  }
  ...

The report method writes directly to System.err. A workaround could be to replace the System.err with System.setErr() before the first LoggerFactory.getLogger() call but you could lose other important messages if you do that.

Of course you can download the source and remove these Util.report calls and use your modified slf4j-api in your project.

like image 71
palacsint Avatar answered Sep 16 '22 12:09

palacsint