slf4j jar包冲突和spring的bean解析错误
由于种种原因,项目的结构被调整成了ant+maven共同管控的样子(真的好挫)
于是,一个最基本的问题来了,之前写的UT没法跑了。
首先爆出来的是slf4j的问题:
SLF4J: See http://www.slf4j.org/codes.html#version_mismatch for further details. Exception in thread "main" java.lang.NoSuchMethodError: org.slf4j.spi.LocationAwareLogger.log(Lorg/slf4j/Marker;Ljava/lang/String;ILjava/lang/String;[Ljava/lang/Object;Ljava/lang/Throwable;)V at org.apache.commons.logging.impl.SLF4JLocationAwareLog.info(SLF4JLocationAwareLog.java:159) at org.springframework.context.support.AbstractApplicationContext.prepareRefresh(AbstractApplicationContext.java:456) at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:394) at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140) at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:94) at main.Run.main(Run.java:33)
到依赖的classpath里面一find,发现下面至少有1.4.3、1.5.10、1.5.6、1.6.1几个版本的slf4j的jar包共存。。。
处理方案:
全部干掉,仅保留一套最slf4j组件,即:留个接口包: slf4j-api,留个实现包:slf4j-log4j12。
一位搞定这个问题了,结果spring的bean解析又出问题了。。。
Caused by: java.lang.NoSuchFieldError: fRecognizedFeatures at org.apache.xerces.parsers.BasicParserConfiguration.<init>(Unknown Source) at org.apache.xerces.parsers.DTDConfiguration.<init>(Unknown Source) at org.apache.xerces.parsers.StandardParserConfiguration.<init>(Unknown Source) at org.apache.xerces.parsers.IntegratedParserConfiguration.<init>(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.<init>(Unknown Source) at org.apache.xerces.parsers.XML11Configuration.<init>(Unknown Source) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) at java.lang.reflect.Constructor.newInstance(Constructor.java:513) at java.lang.Class.newInstance0(Class.java:355) at java.lang.Class.newInstance(Class.java:308) at org.apache.xerces.util.ObjectFactory.newInstance(Unknown Source) at org.apache.xerces.util.ObjectFactory.findJarServiceProvider(Unknown Source) at org.apache.xerces.util.ObjectFactory.createObject(Unknown Source) at org.apache.xerces.util.ObjectFactory.createObject(Unknown Source) at org.apache.xerces.parsers.DOMParser.<init>(Unknown Source) at org.apache.xerces.parsers.DOMParser.<init>(Unknown Source) at org.apache.xerces.jaxp.DocumentBuilderImpl.<init>(Unknown Source) at org.apache.xerces.jaxp.DocumentBuilderFactoryImpl.setAttribute(Unknown Source) at org.springframework.beans.factory.xml.DefaultDocumentLoader.createDocumentBuilderFactory(DefaultDocumentLoader.java:99) at org.springframework.beans.factory.xml.DefaultDocumentLoader.loadDocument(DefaultDocumentLoader.java:70) at org.springframework.beans.factory.xml.XmlBeanDefinitionReader.doLoadBeanDefinitions(XmlBeanDefinitionReader.java:396) ... 34 more
这次又是因为xml.xerces.jar和jdk自带的xml解析工具类冲突导致的,又是jar包冲突!!!
这个问题的解决方案有好几个,可以参考:这里
1、Use the “javax.xml.parsers.DocumentBuilderFactory” system property.
2、Use the properties file "lib/jaxp.properties" in the JRE directory.
3、Use the Services API (as detailed in the JAR specification), if available, to determine the classname. The Services API will look for a classname in the file “META-INF/services/javax.xml.parsers.DocumentBuilderFactory" in jars available to the runtime.
4、Platform default "DocumentBuilderFactory" instance,也就是类com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl。
我采用了一种简单的方式,在jvm的启动参数中加上下面的参数明确制定要用哪个实现类。
-Djavax.xml.parsers.DocumentBuilderFactory=com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl -Djavax.xml.parsers.SAXParserFactory=com.sun.org.apache.xerces.internal.jaxp.SAXParserFactoryImpl