用tomcat8部署一web工程启动时报错如下:
Caused by: java.lang.IllegalAccessError: tried to access field org.slf4j.impl.StaticLoggerBinder.SINGLETON from class org.slf4j.LoggerFactory
at org.slf4j.LoggerFactory.<clinit>(LoggerFactory.java:65)
at com.foo.util.rds.Subscriber.afterPropertiesSet(Subscriber.java:93)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1571)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1509)
... 20 more
该web工程依赖的日志jar包有如下几个
其中slf4j-log4j13-1.0.1中的LoggerFactory 65行代码如下
loggerFactory = StaticLoggerBinder.SINGLETON.getLoggerFactory();
而slf4j-api-1.7.6中也有LoggerFactory,但是它俩内容不同, slf4j-api-1.7.6中LoggerFactory的65行内容为
static final String UNSUCCESSFUL_INIT_MSG = "org.slf4j.LoggerFactory could not be successfully initialized. See also "
+ UNSUCCESSFUL_INIT_URL;
另外slf4j-log4j13-1.0.1中存在StaticLoggerBinder,其中SINGLETON为公有静态属性
public static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
而slf4j-jdk14-1.7.7和logback-classic-1.1.2中也有StaticLoggerBinder, 且他们中的SINGLETON为私有的
private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();
如果用的是slf4j-log4j13-1.0.1中的LoggerFactory,但StaticLoggerBinder用的又是其他jar包的,就会报上述错误
在tomcat的启动脚本(catalina.sh)中设置了jvm参数打印类加载信息(JAVA_OPTS="$JAVA_OPTS -XX:+TraceClassLoading"),果然如上所述
[Loaded org.slf4j.LoggerFactory from file:/home/zhuguowei/shicaigj/scgj-admin/target/scgj-admin/WEB-INF/lib/slf4j-log4j13-1.0.1.jar]
[Loaded org.slf4j.impl.StaticLoggerBinder from file:/home/zhuguowei/shicaigj/scgj-admin/target/scgj-admin/WEB-INF/lib/slf4j-jdk14-1.7.7.jar]
而在tomcat7中能成功部署, 看一下tomcat7中的加载信息
[Loaded org.slf4j.LoggerFactory from file:/home/zhuguowei/shicaigj/scgj-admin/target/scgj-admin/WEB-INF/lib/slf4j-api-1.7.6.jar]
...
[Loaded org.slf4j.impl.StaticLoggerBinder from file:/home/zhuguowei/shicaigj/scgj-admin/target/scgj-admin/WEB-INF/lib/logback-classic-1.1.2.jar]
解决方法
参考一个开源项目(springside)修改root-pom 将依赖的slf4jjar包修改为
<slf4j.version>1.7.8</slf4j.version>
<logback.version>1.1.2</logback.version>
<!-- LOGGING begin -->
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback.version}</version>
</dependency>
<!-- 代码直接调用log4j会被桥接到slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- 代码直接调用commons-logging会被桥接到slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency>
<!-- 代码直接调用java.util.logging会被桥接到slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</dependency
<!-- LOGGING end -->
补充
该web工程用tomcat8不能成功加载, 原因是slf4jjar包冲突, 目前的解决方法是改用了tomcat7
但用了tomcat7 出现了中文乱码的问题, 需要修改server.xml
在Connector元素中添加一个属性: URIEncoding="UTF-8"
如下所示:
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" />
参考了该博客:
http://blog.csdn.net/renfufei/article/details/11294917
而tomcat8不需要显式做此设置