在本章中,我們將討論在使用SLF4J時獲得的各種錯誤消息或警告以及這些消息的原因/含義。
無法加載類“org.slf4j.impl.StaticLoggerBinder”。
這是在類路徑中沒有提供SLF4J綁定時引起的警告。
以下是完整的警告 -
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.
要解決此問題,需要添加任一日誌框架綁定。本教學上一小節對此進行瞭解釋說明。
注 - 這種情況發生在SLF4J的版本中,介於1.6.0和1.8.0-beta2之間。
No SLF4J providers were found
在slf4j-1.8.0-beta2中,上述警告更清楚地說“未找到SLF4J提供商”。
以下是完整的警告 -
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包含針對1.8之前的slf4j-api版本的SLF4J綁定
如果使用的是SLF4J 1.8版本,並且在類路徑中具有以前版本的綁定但沒有1.8
的綁定,則會看到如下所示的警告。
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/maxsu/Desktop/Latest%20zaixian/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
,將得到一個例外(異常),例如下麵給出的例外(異常)。
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
添加到類路徑中。
Detected both jcl-over-slf4j.jar AND bound slf4j-jcl.jar on the classpath..
綁定slf4j-jcl.jar
將slf4j logger的調用重定向到JCL,jcl-over-slf4j.jar
將JCL logger的調用重定向到slf4j。因此,不能在專案的類路徑中同時擁有這兩者。如果這樣做,會得到一個例外(異常),例如下麵給出的(異常)。
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檔。
Detected logger name mismatch
可以通過以下方式創建Logger
對象:
- 將要創建的記錄器的名稱作為參數傳遞給
getLogger()
方法。 - 將類作為參數傳遞給此方法。
如果通過將類作為參數傳遞來創建記錄器工廠對象,並且已將系統屬性slf4j.detectLoggerNameMismatch
設置為true
,那麼作為參數傳遞給getLogger()
方法的類的名稱和使用類應該相同,否則將收到以下警告 -
“Detected logger name mismatch”
請考慮以下示例。
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 xuhuhu.com");
}
}
在這裏,將slf4j.detectLoggerNameMismatch
屬性設置為true
。使用的類的名稱是SLF4JExample
,傳遞給getLogger()
方法的類名是Sample
,因為它們都不相等,將會收到以下警告。
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, 2019 10:23:00 PM SLF4JExample main
INFO: Hi Welcome to xuhuhu.com
注 - 它在slf4j 1.7.9之後發生
Classpath contains multiple SLF4J bindings.
應該在類路徑中只有一個綁定。如果有多個綁定,將收到一個警告,列出綁定及其位置。
假設,如果在類路徑中有綁定slf4j-jdk14.jar
和slf4j-nop.jar
,將收到以下警告。
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in
[jar:file:/C:/Users/zaixian/Desktop/Latest%20zaixian/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/zaixian/Desktop/Latest%20zaixian/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 logger調用重定向到slf4j,需要使用log4j-over-slf4j.jar
綁定,如果要將slf4j調用重定向到log4j,則需要使用slf4j-log4j12.jar
綁定。
因此,不能在類路徑中同時擁有這兩者。如果這樣做,將收到以下異常。
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.