这是前几天碰到的一个由 SLF4J 引发的异常
Exception in thread "main" java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:60)
在网上搜索时,找到了 SLF4J FAQ 这篇文档,其中就有对这个异常的描述,当时是把问题解决了。为了将这个问题的解决过程描述方便,我先写了之前的一篇文章,简单介绍了一些 SLF4J 的知识。因为这个异常的产生原因是由于 slf4j-api.jar 与 slf4j-log4j12.jar 版本不兼容所致,其中 slf4j-log4j12.jar 是 SLF4J 提供的五种 binding jar 之一。具体的说,是由于使用了较老版本的 slf4j-api.jar(在我的应用里引的版本是 1.4.1),和较新版本的 slf4j binding jar(在我的应用里引了 slf4j-log4j12-1.5.6.jar)。
错误的出处是: 我定义了一个类,为了使用 log4j 打印日志,调用 org.slf4j.LoggerFactory 创建了一个 Logger,并作为类的 static 属性,除此之外无其他的成员属性,代码如下:
public class Foo { private static final Logger logger = LoggerFactory.getLogger(Foo.class); // ... methods }
在获取 Logger 时抛了前面的异常。
下面通过源码分析下异常的来源:
在 slf4j-api 的早期版本(1.5.5 及之前)中,org.slf4j.LoggerFactory 中包含一个 ILoggerFactory 的 static 属性,并且通过 static 块进行初始化。
public final class LoggerFactory { static ILoggerFactory loggerFactory; static { try { loggerFactory = StaticLoggerBinder.SINGLETON.getLoggerFactory(); } catch(NoClassDefFoundError ncde) { //... } }
在早期版本的 slf4j binding 实现中,org.slf4j.impl.StaticLoggerBinder 类中的 SINGLETON 成员是被定义为 public 的。
public class StaticLoggerBinder { /** * The unique instance of this class. */ public static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder(); public ILoggerFactory getLoggerFactory() { //... } }
所以,如果 slf4j-api.jar 和 slf4j-log4j12.jar 都使用早期版本,将不会报错。
从 SLF4J 1.5.6 开始, slf4j binding 实现中的 org.slf4j.impl.StaticLoggerBinder 类的 SINGLETON 被定义为了 private. 并且从这个版本开始,slf4j api 中 org.slf4j.LoggerFactory 不再使用 StaticLoggerBinder.SINGLETON.getLoggerFactory() 的方式获取 ILoggerFactory 的实例,而是通过 StaticLoggerBinder.getSingleton.getLoggerFactory() 的方式对 ILoggerFactory 实例进行初始化。具体的实现要比早期版本复杂的多,在此不详细列代码了。
所以,如果使用早期版本的 slf4j-api.jar 和新版本的 slf4j binding jar,由于 org.slf4j.LoggerFactory 无法访问新版本 binding 实现中的 StaticLoggerBinder.SINGLETON 私有属性,就会产生前面的异常信息。
相关推荐
slf4j-api和slf4j-nop打包下载,只需解压文件,就能得到slf4j-api.jar和slf4j-nop.jar
slf4j-api.jar slf4j-api.jar slf4j-api.jar slf4j-api.jar
1.7.21-sources.jar 7、osgi-over-slf4j-1.7.21.jar 8、osgi-over-slf4j-1.7.21-sources.jar 9、slf4j-android-1.7.21.jar 10、slf4j-android-1.7.21-sources.jar 11、slf4j-api-1.7.21.jar 12、slf4j-api-1.7.21-...
赠送jar包:slf4j-api-1.7.26.jar; 赠送原API文档:slf4j-api-1.7.26-javadoc.jar; 赠送源代码:slf4j-api-1.7.26-sources.jar; 赠送Maven依赖信息文件:slf4j-api-1.7.26.pom; 包含翻译后的API文档:slf4j-api-...
赠送jar包:slf4j-api-1.7.32.jar; 赠送原API文档:slf4j-api-1.7.32-javadoc.jar; 赠送源代码:slf4j-api-1.7.32-sources.jar; 赠送Maven依赖信息文件:slf4j-api-1.7.32.pom; 包含翻译后的API文档:slf4j-api-...
slf4j-api-1.6.0.jar,slf4j-jdk14-1.6.0.jar,slf4j-log4j12-1.6.0-rc0.jar,slf4j-nop-1.6.0.jar,slf4j-simple-1.6.0.jar
赠送jar包:slf4j-api-1.8.0-alpha2.jar; 赠送原API文档:slf4j-api-1.8.0-alpha2-javadoc.jar; 赠送源代码:slf4j-api-1.8.0-alpha2-sources.jar; 赠送Maven依赖信息文件:slf4j-api-1.8.0-alpha2.pom; 包含...
赠送jar包:slf4j-api-1.7.16.jar; 赠送原API文档:slf4j-api-1.7.16-javadoc.jar; 赠送源代码:slf4j-api-1.7.16-sources.jar; 赠送Maven依赖信息文件:slf4j-api-1.7.16.pom; 包含翻译后的API文档:slf4j-api-...
slf4j-api-1.7.30.jar
slf4j-api-1.7.12.jar slf4j-log4j12-1.7.12.jar
与slf4j-nop-1.7.25.jar相匹配的版本信息slf4j-api-1.7.25.jar
1.7.21-sources.jar 7、osgi-over-slf4j-1.7.21.jar 8、osgi-over-slf4j-1.7.21-sources.jar 9、slf4j-android-1.7.21.jar 10、slf4j-android-1.7.21-sources.jar 11、slf4j-api-1.7.21.jar 12、slf4j-api-1.7.21-...
压缩包包含slf4j-log4j12-1.7.12.jar和slf4j-api-1.7.12.jar
11、slf4j-api-1.7.21.jar 12、slf4j-api-1.7.21-sources.jar 13、slf4j-ext-1.7.21.jar 14、slf4j-ext-1.7.21-sources.jar 15、slf4j-jcl-1.7.21.jar 16、slf4j-jcl-1.7.21-sources.jar 17、slf4j-jdk14-...
slf4j-api-1.6.4.jar
slf4j-api-1.6.6.jar, Simple Logger Facade for Java的核心包
赠送jar包:slf4j-api-1.6.6.jar; 赠送原API文档:slf4j-api-1.6.6-javadoc.jar; 赠送源代码:slf4j-api-1.6.6-sources.jar; 赠送Maven依赖信息文件:slf4j-api-1.6.6.pom; 包含翻译后的API文档:slf4j-api-...
slf4j.api-1.6.1.jar 开源的日志开发工具类,日常开发的神器
org.slf4j.ILoggerFactory.class org.slf4j.IMarkerFactory.class org.slf4j.Logger.class org.slf4j.LoggerFactory.class org.slf4j.MDC.class org.slf4j.Marker.class org.slf4j.MarkerFactory.class org.slf4j....
开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22开发工具 slf4j-api-1.7.22...