Slf4j 简明教程
SLF4J - Error Messages
在本章中,我们将讨论在使用 SLF4J 时收到的各种错误消息或警告,以及这些消息的原因/含义。
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".
当类路径中没有提供 SLF4J 绑定时,会引发此警告。
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.
要解决此问题,您需要添加日志记录框架绑定之一。这是在本教程的 Hello world 章中进行说明的。
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 − 这种情况发生在 SLF4J 1.6.0 至 1.8.0-beta2 之间的版本中。
Note − This occurs in versions of SLF4J which are between 1.6.0 and 1.8.0-beta2.
No SLF4J providers were found
在 slf4j-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
如果您使用的是 SLF4J 1.8 版本,并且您在类路径中具有以前版本的绑定,但没有 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/Tutorialspoint/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
如果您使用 slf4j-jcl ,并且您在类路径中只有 slf4j-jcl.jar ,您将收到如下所示的异常。
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
为了解决此问题,你需要将 commons-logging.jar 添加到你的 classpath 中。
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..
绑定 slf4j-jcl.jar 将 SLF4J 日志记录器的调用重定向到 JCL,绑定 jcl-over-slf4j.jar 将 JCL 日志记录器的调用重定向到 SLF4J。因此,在项目的 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
为了解决此问题,删除这两个 jar 文件中的任意一个。
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.
如果你试图通过将类作为参数传递来创建日志记录器工厂对象,而且你将系统属性 slf4j.detectLoggerNameMismatch 设置为 true,那么你传递给 getLogger() 方法的参数所属类的名称和你使用的类应当相同,否则你会收到下列警告:
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");
}
}
在此,我们已将 slf4j.detectLoggerNameMismatch 属性设置为 true。我们使用的类名为 SLF4JExample ,而我们传递给 getLogger() 方法的类名为 Sample ,由于这两个名称不相等,因此会收到以下警告。
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 - 这发生在 SLF4J 1.7.9 之后
Note − This occurs after slf4j 1.7.9
Classpath contains multiple SLF4J bindings.
你应该在 classpath 中只保留一个绑定。如果你有多个绑定,你将会收到一条警告,列出这些绑定及其位置。
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.
假设 classpath 中有绑定 slf4j-jdk14.jar 和 slf4j-nop.jar ,那么我们将会收到以下警告。
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/Tutorialspoint/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/Tutorialspoint/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
要将 Log4j 日志记录器调用重新定向到 SLF4J,你需要使用 log4j-over-slf4j.jar 绑定,如果你想将 SLF4J 调用重新定向到 Log4j,则需要使用 slf4j-log4j12.jar 绑定。
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.
因此,你不能在 classpath 中同时拥有两者。如果你这样做,你会收到以下异常。
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.