Resolving Multiple SLF4J Binding Warning

If you develop in Java long enough, you will eventually come across the Multiple Binding warning that looks something like the following:


SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/C:/app/.m2/repository/ch/qos/logback/logback-classic/1.1.11/logback-classic-1.1.11.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/app/.m2/repository/org/slf4j/slf4j-log4j12/1.7.24/slf4j-log4j12-1.7.24.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/C:/app/.m2/repository/org/apache/hive/hive-jdbc/1.1.0/hive-jdbc-1.1.0-standalone.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 [ch.qos.logback.classic.util.ContextSelectorStaticBinder]

In this specific case, the warning is stating that SLF4J was found in three different packages (logback-classic, slf4j and hive). Then it states which binding it actually picks up.

This is a warning that should have no consequences if left alone. As the SLF4J link mentioned in the warning notes:

The warning emitted by SLF4J is just that, a warning. Even when multiple bindings are present, SLF4J will pick one logging framework/implementation and bind with it. The way SLF4J picks a binding is determined by the JVM and for all practical purposes should be considered random. As of version 1.6.6, SLF4J will name the framework/implementation class it is actually bound to.

Embedded components such as libraries or frameworks should not declare a dependency on any SLF4J binding but only depend on slf4j-api. When a library declares a compile-time dependency on a SLF4J binding, it imposes that binding on the end-user, thus negating SLF4J’s purpose. When you come across an embedded component declaring a compile-time dependency on any SLF4J binding, please take the time to contact the authors of said component/library and kindly ask them to mend their ways.

However, if you are a perfectionist like me, you don’t like seeing this warning every time you run your program. It’s pretty easy to remove the warning. You go through the packages that have SLF4J bindings, and exclude it from the dependency.

For example, if the binding was found in Hive, you update from dependency declaration to:

<dependency>
  <groupId>org.apache.hive</groupId>
  <artifactId>hive-jdbc</artifactId>
  <version>1.1.0</version>
  <classifier>standalone</classifier>
  <exclusions>
   <exclusion>
    <artifactId>jetty-all</artifactId>
    <groupId>org.eclipse.jetty.aggregate</groupId>
   </exclusion>
   <exclusion>
     <groupId>org.slf4j</groupId>
     <artifactId>slf4j-log4j12</artifactId>
   </exclusion>
  <exclusion>
     <groupId>log4j</groupId>
     <artifactId>log4j</artifactId>
   </exclusion>
  </exclusions>

 </dependency>

Author: Dev

Full Stack Developer at one of the largest Banks in Canada.