SLF4J - Error Messages


Advertisements

In this chapter, we will discuss the various error messages or warning we get while working with SLF4J and the causes/ meanings of those messages.

Failed to load class "org.slf4j.impl.StaticLoggerBinder".

This is a warning which is caused when there are no SLF4J bindings provided in the classpath.

Following is the complete warning −

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further
details.

To resolve this, you need to add either of the logging framework bindings. This is explained in the Hello world chapter of this tutorial.

Note − This occurs in versions of SLF4J which are between 1.6.0 and 1.8.0-beta2.

No SLF4J providers were found

In slf4j-1.8.0-beta2, the above warning is more clear saying “No SLF4J providers were found”.

Following is the complete warning −

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.

Classpath contains SLF4J bindings targeting slf4j-api versions prior to 1.8

If you are using SLF4J 1.8 version and you have the bindings of previous versions in the classpath but not the bindings of 1.8 you will see a warning as shown below.

SLF4J: No SLF4J providers were found.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#noProviders for further details.
SLF4J: Class path contains SLF4J bindings targeting slf4j-api versions prior to
1.8.
SLF4J: Ignoring binding found at
[jar:file:/C:/Users/Howcodex/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/
slf4j-1.7.25/slf4j-jdk14-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#ignoredBindings for an explanation.

NoClassDefFoundError: org/apache/commons/logging/LogFactory

If you are working with slf4j-jcl and if you have only slf4j-jcl.jar in your classpath, you will get an exception such as the one given below.

Exception in thread "main" java.lang.NoClassDefFoundError:
org/apache/commons/logging/LogFactory
   at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:77)
   at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
   at SLF4JExample.main(SLF4JExample.java:8)
Caused by: java.lang.ClassNotFoundException:
org.apache.commons.logging.LogFactory
   at java.net.URLClassLoader.findClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
   at java.lang.ClassLoader.loadClass(Unknown Source)
   ... 3 more

To resolve this, you need to add commons-logging.jar to your classpath.

Detected both jcl-over-slf4j.jar AND bound slf4j-jcl.jar on the classpath..

The binding slf4j-jcl.jar redirects calls of the slf4j logger to JCL and the jcl-over-slf4j.jar redirects calls of JCL logger to slf4j. Therefore, you cannot have both in the classpath of your project. If you do so, you will get an exception such as the one given below.

SLF4J: Detected both jcl-over-slf4j.jar AND bound slf4j-jcl.jar on the class
path, preempting StackOverflowError.
SLF4J: See also http://www.slf4j.org/codes.html#jclDelegationLoop for more
details.
Exception in thread "main" java.lang.ExceptionInInitializerError
   at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:71)
   at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:42)
   at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
   at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
   at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
   at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
   at SLF4JExample.main(SLF4JExample.java:8)
Caused by: java.lang.IllegalStateException: Detected both jcl-over-slf4j.jar
AND bound slf4j-jcl.jar on the class path, preempting StackOverflowError. See
also http://www.slf4j.org/codes.html#jclDelegationLoop for more details.
   at org.slf4j.impl.JCLLoggerFactory.<clinit>(JCLLoggerFactory.java:54)
   ... 7 more

To resolve this, delete either of the jar files.

Detected logger name mismatch

You can create a Logger object by −

  • Passing the name of the logger to be created as an argument to the getLogger() method.

  • Passing a class as an argument to this method.

If you are trying to create the logger factory object by passing a class as an argument, and if you have set the system property slf4j.detectLoggerNameMismatch to true, then the name of the class you pass as an argument to the getLogger() method and the class you use should be the same otherwise you will receive the following warning −

“Detected logger name mismatch.

Consider the following example.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SLF4JExample {
   public static void main(String[] args) {
      System.setProperty("slf4j.detectLoggerNameMismatch", "true");
      
      //Creating the Logger object
      Logger logger = LoggerFactory.getLogger(Sample.class);

      //Logging the information
      logger.info("Hi Welcome to Tutorilspoint");
   }
}

Here, we have set the slf4j.detectLoggerNameMismatch property to true. The name of the class we used is SLF4JExample and the class name we have passed to the getLogger() method is Sample since they both are not equal we will get the following warning.

SLF4J: Detected logger name mismatch. Given name: "Sample"; computed name:
"SLF4JExample".
SLF4J: See http://www.slf4j.org/codes.html#loggerNameMismatch for an
explanation
Dec 10, 2018 12:43:00 PM SLF4JExample main
INFO: Hi Welcome to Tutorilspoint

Note − This occurs after slf4j 1.7.9

Classpath contains multiple SLF4J bindings.

You should have only one binding in the classpath. If you have more than one binding, you will get a warning listing the bindings and the locations of them.

For suppose, if we have the bindings slf4j-jdk14.jar and slf4j-nop.jar in the classpath we will get the following warning.

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in
[jar:file:/C:/Users/Howcodex/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/
slf4j-1.7.25/slf4j-nop-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in
[jar:file:/C:/Users/Howcodex/Desktop/Latest%20Tutorials/SLF4J%20Tutorial/
slf4j-1.7.25/slf4j-jdk14-1.7.25.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.helpers.NOPLoggerFactory]

Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the class path

To redirect the log4j logger calls to slf4j, you need to use log4j-over-slf4j.jar binding and if you want to redirect slf4j calls to log4j, you need to use slf4j-log4j12.jar binding.

Therefore, you cannot have both in the classpath. If you do, you will get the following exception.

SLF4J: Detected both log4j-over-slf4j.jar AND bound slf4j-log4j12.jar on the
class path, preempting StackOverflowError.
SLF4J: See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more
details.
Exception in thread "main" java.lang.ExceptionInInitializerError
   at org.slf4j.impl.StaticLoggerBinder.<init>(StaticLoggerBinder.java:72)
   at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:45)
   at org.slf4j.LoggerFactory.bind(LoggerFactory.java:150)
   at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:124)
   at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:412)
   at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:357)
   at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
   at SLF4JExample.main(SLF4JExample.java:8)
Caused by: java.lang.IllegalStateException: Detected both log4j-over-slf4j.jar
AND bound slf4j-log4j12.jar on the class path, preempting StackOverflowError.
See also http://www.slf4j.org/codes.html#log4jDelegationLoop for more details.
Advertisements