用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不需要显式做此设置