《SLF4J官方文档》SLF4J警告或错误信息及其含义

调用方法o.a.commons.logging.impl.SLF4FLogFactory.release

已给出的公用日志API(common-logging API),实际上是由SLF4J实现的,o.a.commons.logging.impl.SLF4FLogFactory.release方法永远不会被调用。然而,取决于commons-logging.jar在服务器小程序容器的部署,release()方法可能意外地通过commons-logging.jar装载的org.apache.commons.logging.LogFactoryl类被调用。

当Tomac安装后,$TOMAC_HOME代表目录;在最近的Tomac版本上,这是个普遍的现象,尤其当你在应用中在WEB-INF/lib下放置jcl-over-slf4j.jar而不是在$TOMCAT_HOME/common/lib下放置jar包。为了完全获得jcl-over-slf4j.jar包的稳定性,我们建议你在$TOMCAT_HOME/common/lib目录下放置jcl-over-slf4j.jar包,没有在你的web应用里放置副本。

也请你看下bug#22

jcl-over-slf4j不支持的[某个]操作

当调用JCL1.1中受保护的方法,会抛出不支持操作异常 (UnsupportedOperationException)。这些方法都是通过commons-logging.jarLogFactory 实现调用。 当然,LogFactory由 jcl-over-slf4j.jar包下的SLF4FLogFactory实现,SLF4FLogFactory不调用这些方法。

如果你研究这个问题,很大可能是你的commons-logging.jar副本在类的路径下覆盖了jcl-over-slf4j.jar包中的类。

当调用o.a.commons.logging.impl.SLF4FLogFactory.release()方法时,注意实际上这个问题跟发出的警告是非常相似的,已在前一个章节讨论了。

日志名称不匹配检测

只有slf4j.detectLoggerNameMismatch系统属性设置为true时,日志名称不匹配警告才会打印。默认情况下,这个属性没有设置,即使在日志名称不匹配的情况下也不会打印警告。

从1.7.9开始,在指定名称的日志器下,向LoggerFactory.getLogger(Class)方法传参,警告信息就会被打印,这个方法和SLF4J内部推断的调用者的名称不同。

例如,代码块如下:

package com.acme;
import com.foo.Kangaroo;

class <strong>Fruit</strong> {
Logger logger = LoggerFactory.getLogger(Kangaroo.class);
}

结果将会显示:

SLF4J: Detected logger name mismatch. Given name:

"com.foo.Kangaroo"; computed name: "com.acme.Fruit".

但只在slf4j.detectLoggerNameMismatch系统属性设置为true时才显示。

当日志器中传入的参数类是一个基类,这种特定情况下子类不会出现任何警告信息,例如:

class A {
Logger logger = LoggerFactory.getLogger(getClass());
}
class B extends A {
// no mismatch warning will be issued when B is instantiated
// given that class A is a super-type of class B
}

如果你遇到不能解释的不匹配警告,你可以用白色大象标记它,当定义了日志器,这种不能正确推断出类名的情况是非常少的。我们也很有兴趣去获得这些类。如果你标记了一个无法解释的不匹配信息,请给我们发一个[日志报告]( http://www.slf4j.org/bug-reporting.html)文件。

加载org.slf4j.impl.StaticLoggerBinder类失败

当org.slf4j.impl.StaticLoggerBinder类不能从内存中加载是,将会报告这个错误信息。当在类路径中没有合适的SLF4J绑定时,这种情况会发生。放置一个jar包(只能放其中的一个):slf4j-nop.jar, slf4j-simple.jar, slf4j-log4j12.jar, slf4j-jdk14.jar, logback-classic.jar。在类路径中放置一个就可以解决问题。

从1.6.0: 1.6版本的SLF4J,没有绑定,SLF4J默认是一个无操作日志实现。

你可以从项目下载页(http://www.slf4j.org/download.html)下载SLF4J绑定。

在类路径下发现多个绑定

SLF4J被设计成依次与每个且只有一个基本日志框架绑定。如果在类路径下存在不止一个绑定。SLF4J将发出一个警告,列出这些绑定的位置。

当多个绑定在类路径下,只能选取一个你想用的绑定,移除其他绑定。比如,如果在类路径下同时有slf4j-simple-1.7.19.jar和 slf4j-nop-1.7.19.jar,你想用无操作绑定,那么把slf4j-nop-1.7.19.jar从类路径中移除。

这个SLF4J提供的警告信息位置列表 为识别过渡添加到项目中不想要的SLF4J绑定依赖包 提供了有效的信息。在项目中pom.xml文件中,剔除掉那些随意声明的依赖包下的SLF4J绑定。例如,cassandra-all版本0.0.1同时把log4jslf4j-log4j12声明为编译时间关联。由此,当你把cassandra-all作为依赖包包含到你的项目中,cassandra-all声明将导致log4jslf4j-log4j12同时被添加为依赖包。假使SLF4J在后台时,你不想用log4J,你可以告诉Maven这俩个文件,如下文显示:

<dependencies>
 <dependency>
  <groupId> org.apache.cassandra</groupId>
  <artifactId>cassandra-all</artifactId>
  <version>0.8.1</version>

  <exclusions>
   <exclusion>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
   </exclusion>
   <exclusion>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
   </exclusion>
  </exclusions>

 </dependency>
</dependencies>

注意:SLF4J发出的警告只是警告。甚至多个绑定存在时,SLF4J将选取一个日志框架/实现,然后与它绑定。SLF4J选取绑定的方式由java虚拟机决定,应该随机考虑所有的实际目的。1.6.6版本,SLF4J会以框架/实现类的实际范围命名。

例如类库或框架的这些嵌入的组件不能声明任何SLF4J的绑定,除了依赖slf4j-api。当一个包库在SLF4J绑定上声明一个编译时间依赖,它会欺骗你并且绑定到最后的用户,这样就与 SLF4J的目的背道而驰了。当你遇到嵌入组件在SLF4J绑定上声明编译时间依赖,请及时联系这些作者,友好地请他们修复这些方法。

Slf4j-api版本不匹配绑定

SLF4J绑定标明人工打的jar包,例如用来把slf4j绑定到基本日志框架的slf4j-jdk14.jar 或 slf4j-log4j12.jar,java.util.logging和个别log4j。

混用不同版本的slf4j-api.jar和SLF4J绑定会导致问题。例如,如果你用slf4j-api-1.7.19.jar,然后你也应该用slf4j-simple-1.7.19.jar,用slf4j-simple-1.5.5.jar将不起作用。

注意: 从客户端的角度,所有版本的slf4j-api版本都是兼容的。在任意N和M版本slf4j-api下,通过slf4j-api-N.jar编译的客户端代码在slf4j-api-M.jar下也将运行良好。你只需确定绑定版本匹配slf4j.jar。你不需要担心项目中已给出的依赖库slf4j-api的版本。你能用任意slf4j-api.jar版本,只要slf4j-api.jar版本和它的绑定匹配,就不会有问题。

在初始化时,如果SLF4J怀疑有任任何api和绑定版本不匹配问题,它将发出被疑似不匹配的警告信息。

日志工厂实现不能为空

这个错误在LoggerFactory类找不到合适的绑定时会报告。在类路径下放置slf4j-nop.jar, slf4j-simple.jar, slf4j-log4j12.jar, slf4j-jdk14.jar logback-classic.jar中的一个包(只能放一个),这会是个有效的改正方法。

在类路径下检测log4j-over-slf4j.jar和 slf4j-log4j12.jar包,替代堆溢出错误

slf4j-log4j12 模块的目的是把从log4j日志到SLF4J的调用转移或重定向。Log4j-over-slf4j模块的目的是把从Log4j-over-slf4j日志到SLF4J的日志记录重定向。如果SLF4J属于slf4j-log4j12.jar和slf4j-log4j-over-slf4.jar,也会在出现在类路径中,堆溢出错误必然会在第一次调用SLF4J或log4j日志时出现。

如下是类似的异常:

Exception in thread "main" java.lang.StackOverflowError
at java.util.Hashtable.containsKey(Hashtable.java:306)
at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:36)
at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
at org.apache.log4j.Category.<init>(Category.java:53)
at org.apache.log4j.Logger..<init>(Logger.java:35)
at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39)
at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
at org.slf4j.impl.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:73)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
at org.apache.log4j.Category..<init>(Category.java:53)
at org.apache.log4j.Logger..<init>(Logger.java:35)
at org.apache.log4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:39)
at org.apache.log4j.LogManager.getLogger(LogManager.java:39)
subsequent lines omitted...

SINCE 1.5.11  SLF4j取代了必然发生的堆溢出错误,通过抛出一个关于问题实际情况的详情的异常。这比让用户去想堆溢出错误的原因要好多了。

更多其他关于这个主题的更多背景,查看Bridging legacy APIs(http://www.slf4j.org/legacy.html)。

在类路径下检测jcl-over-slf4j.jar 和 slf4j-jcl.jar包,替代堆溢出错误

slf4j-jcl模块的目的是把从SLF4J到JCL(jakarta commons logging)的调用转移或重定向。jcl-over-slf4j模块的目的是从JCL日志到SLF4J的日志记录转移或重定向。如果SLF4J属于jcl-over-slf4j.jar和slf4j-jcl.jar,也会在出现在类路径中,堆溢出错误必然会立即在第一次调用SLF4J或JCL日志时出现。

如下是类似的异常:

Exception in thread "main" java.lang.StackOverflowError
at java.lang.String.hashCode(String.java:1482)
at java.util.HashMap.get(HashMap.java:300)
at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:67)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:289)
at org.slf4j.impl.JCLLoggerFactory.getLogger(JCLLoggerFactory.java:69)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:249)
at org.apache.commons.logging.impl.SLF4JLogFactory.getInstance(SLF4JLogFactory.java:155)
subsequent lines omitted...

从版本 1.5.11开始  SLF4j取代了必然发生的堆溢出错误,通过抛出一个关于问题实际情况的详情的异常。这比让用户去想堆溢出错误的原因要好多了。

更多其他关于这个主题的更多背景,查看Bridging legacy APIs

加载类” org.slf4j.impl.StaticMDCBinder”失败

这个错误表明在类路径下没找到合适的SLF4J绑定。在类路径下放置slf4j-nop.jar, slf4j-simple.jar, slf4j-log4j12.jar, slf4j-jdk14.jar logback-classic.jar中的一个包(只能放一个)会解决这个问题。

MDCAdapter不能为空

当org.slf4j.MDC class类没有被正确地初始化时会报告此错误。像上面已列出的项一样的情况和改正方案。

 

在初始化阶段拦截一定数量(N)的日志记录,现在重新显示。这些遵循底层日志系统过滤规则

从1.7.版本,在初始化阶段产生的日志记录被记录下来,然后在初始化完成后重新显示。注意重新显示的日志记录遵循底层日志系统过滤规则。

原则上,应用中重新显示出现在第一次日志记录发生时,这时多线程已经启动。

查看substitute loggers

在底层日志系统的默认配置阶段创建替代日志器

像logback和log4j这样的高级可配置日志系统,它们会在自身初始化过程中创建可调用日志器的组件。查看典型的事件LOGBACK-127(http://jira.qos.ch/browse/LOGBACK-127),它不可能实现这样的日志创建请求。

为了避免这种鸡和蛋问题,在这个过程中(初始化),SLF4J创建了替代日志器。在此阶段替代日志器的记录被简单地扔掉了。在初始化完成后,替代日志器将转移记录早合适的日志器实现,不然将会作用在LogFactory返回的日志器上。

如果已创建任何替代日志器,SLF4J将发出一个日志的列表。这个列表意欲让你知道在初始化过程中被这些日志器抛弃的任何日志记录。

查看intercepted and replayed logging calls

SLF4J 1.4.0版本,需要1.2.12及以上的版本

在2005.8.29发布的log4j1.2.12版本增加了跟踪等级。在2007.5.16的SLF4J API中增加了跟踪等级。这样,,启动SLF4J1.4.0时,绑定给SLF4J的log4j需要log4j1.2.12及其以上的版本。

当然,像在文件59报告的一样(http://jira.qos.ch/browse/SLF4J-59),在你某些环境下,这可能会很难升级log4j版本。为了解决这样的情况,SLF4J的Log4jLOggerAdapter将把跟踪等级指为调试级别。

 

java.lang.NoClassDefFoundError: org/slf4j/event/LoggingEvent

Logback-classic version 1.1.4及其以后的版本需要1.7.15及其以上版本的slf4j-api。

类路径中的早期slf4j-api.jar,1.1.4及其以后的logback版本返回的试图内省的日志实例将导致类似于下面显示的NoClassDefFoundError。

Exception in thread "main" java.lang.NoClassDefFoundError: org/slf4j/event/LoggingEvent
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2451)
at java.lang.Class.privateGetPublicMethods(Class.java:2571)
at java.lang.Class.getMethods(Class.java:1429)
at java.beans.Introspector.getPublicDeclaredMethods(Introspector.java:1261)
at java.beans.Introspector.getTargetMethodInfo(Introspector.java:1122)
at java.beans.Introspector.getBeanInfo(Introspector.java:414)
at java.beans.Introspector.getBeanInfo(Introspector.java:161)

在类路径下放置1.7.15及其以上的slf4j-api.jar包可以解决此问题。

记住这个问题只会出现在1.1.4及其以后的logback版本,其他的绑定,例如slf4j-log4j, slf4j-jdk14 and slf4j-simple是不受影响的。

转载自 并发编程网 - ifeve.com

时间: 2024-08-25 11:21:24

《SLF4J官方文档》SLF4J警告或错误信息及其含义的相关文章

《SLF4J官方文档》SLF4J-FAQ 常见问题解答(一)

一般性问题 什么是SLF4J? 什么时候应该使用SLF4J? SLF4J仍是另一个日志外观吗? 如果SLF4J可修复JCL,那为什么不在JCL里加入修复而是创建一个新项目? 使用SLF4J时,我必须重新编译我的应用以转换到一个不同的日志系统吗? SLF4J的要求是什么? SLF4J向后兼容版本吗? 使用SLF4J时遇到访问权限错误,原因是什么? 为什么SLF4J是在X11类型许可证下许可而不是Apache软件许可? 10.在哪里能获得特定的SLF4J绑定? 11.我的库应该尝试配置logging

《SLF4J官方文档》传统桥接API

通常,有些组件取决或依赖Logging API,而不是SLF4J.你也可以假设不久的将来这些组件不会转变成SLF4J.为了处理这种情况,SLF4J装载了几个可以重定向调用的桥接模块,这些模块使得log4j, JCL and java.util.logging APIs 表现得仿佛他们是SLF4J的代替.下图阐述了这个想法. 请注意在你控制下的源代码,你真得应该用slf4j-migrator.本页所描述的基于二进制的解决方案是适合超出你控制范围的软件. 从Jakarta Commons Loggi

《SLF4J官方文档》SLF4J-FAQ 常见问题解答(二)

替代3)空构件 另一种方法是依靠一个空的commons-logging.jar构件.这个聪明的办法首先 由Erik van Oosten想出和最初支持. 空构件可从一个http://version99.qos.ch高可用性Maven仓库,复制在位于不同地域的多个主机. 下面的声明添加version99库设定的Maven的搜索远程资源库. 该存储库中包含的commons-logging和log4j的空构件. 顺便说一句,如果你使用的version99库,请在<version99 AT qos.ch

《SLF4J官方文档》本地化支持

SLF4J-dev邮件列表上的一个讨论产生了一种开源项目叫做CAL10N或编译器辅助定位 . 正如其名所表示的,CAL10N专注于Java应用程序本地化/国际化的问题. 在CALI0N上,附带SLF4J-EXT-1.7.21.jar的org.slf4j.cal10n包的顶部增加了一个非常薄的一层包以提供本地化的日志记录. 一旦你有一个上一个IMessageConveyor实例的句柄,你可以创建LocLoggerFactory ,这反过来又可以创造能够做本地化的日志记录的LocLogger实例.

《Apache Velocity用户指南》官方文档

Quick Start 本项目是 Apache Velocity官方文档的中文翻译版,Velocity类似与JSP,是一种基于Java的模板引擎.它可以在web页面中引用Java代码中定义的数据和对象,而Velocity的作用就是把Web视图和java代码进行组装在一起.本次翻译主要针对对Velocity感兴趣和工作中使用到Velocity的开发人员提供有价值的中文资料,希望能够对大家的工作和学习有所帮助. 由于我也是第一次接触Velocity,还不是很深入,翻译的时候也查看了一些博客以及其他网

jQuery 1.4官方文档详细讲述新特性功能

为了庆祝jQuery的四周岁生日, jQuery的团队荣幸的发布了jQuery Javascript库的最新主要版本! 这个版本包含了大量的编程,测试,和记录文档的工作,我们为此感到很骄傲. 我要以个人的名义感谢 Brandon Aaron, Ben Alman, Louis-Rémi Babe, Ariel Flesler, Paul Irish, Robert Kati?, Yehuda Katz, Dave Methvin, Justin Meyer, Karl Swedberg, and

TestNG官方文档中文版(6)-参数

5.5 - Parameters 测试方法不要求是无参数的.你可以在每个测试方法上使用任意数量的参数,并指示 testNG传递正确的参数. 有两种方式用于设置参数:使用testng.xml或者编程式. 5.5.1 - Parameters from testng.xml 如果你要为你的参数使用简单值,你可以在你的testng.xml中明确指定: @Parameters({ "first-name" }) @Test public void testSingleString(String

【Docker官方文档】理解Docker

本文讲的是[Docker官方文档]理解Docker,[编者的话]本文来自Docker的官方文档,详细介绍了Docker的体系结构.重要概念.内部工作机理等内容,推荐不了解Docker内部原理的同学阅读. 什么是Docker? Docker是一个用于开发.交付和运行应用的开放平台,Docker设计用来更快的交付你的应用程序.Docker可以将你的应用程序和基础设施层隔离,并且还可以将你的基础设施当作程序一样进行管理.Docker可以帮助你更块地打包你代码.测试以及部署,并且也可以减少从编写代码到部

《ZooKeeper官方文档》Zookeeper操作指南

原文链接   译者:小村长 About 本项目是 Apache ZooKeeper官方文档的中文翻译版,致力于为有分布式协同项目需求和对 Apache Zookeeper 感兴趣的同学提供有价值的中文资料,希望能够对大家的工作和学习有所帮助. Zookeeper对与做大数据的人来说在熟悉不过了,毕竟经常用于分布式协同服务中,比如Hbase,Strom等大数据组件中经常用到,但是大部分人仅仅把它当着一个小小的工具,从而很少发时间去深入了解它,今天让小村长为你揭开Zookeeper的神秘面纱. 这一