CXF失败,单元测试中出现不兼容ClassChangeError异常



我有一个使用Spring-3.2.Xcxf-2.7.5的应用程序

我正在将cxf导入我春季的应用程序上下文中,如下所示:

<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:cxf.xml" />

然而,当我运行测试时,我会出现以下异常:

java.lang.IllegalStateException: Failed to load ApplicationContext
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:99)
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122)
at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:154)
at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:100)
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
at org.junit.runner.JUnitCore.run(JUnitCore.java:160)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:202)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:65)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cxf' defined in class path resource [META-INF/cxf/cxf.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.apache.cxf.bus.spring.SpringBus]: Constructor threw exception; nested exception is org.apache.cxf.bus.extension.ExtensionException: Could not load extension class org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl.
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1037)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:983)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:487)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:458)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:296)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:293)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:628)
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:128)
at org.springframework.test.context.web.AbstractGenericWebContextLoader.loadContext(AbstractGenericWebContextLoader.java:60)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100)
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64)
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91)
... 28 more
Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [org.apache.cxf.bus.spring.SpringBus]: Constructor threw exception; nested exception is org.apache.cxf.bus.extension.ExtensionException: Could not load extension class org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl.
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:163)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:87)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1030)
... 44 more
Caused by: org.apache.cxf.bus.extension.ExtensionException: Could not load extension class org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl.
at org.apache.cxf.bus.extension.Extension.tryClass(Extension.java:173)
at org.apache.cxf.bus.extension.Extension.getClassObject(Extension.java:185)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.activateAllByType(ExtensionManagerImpl.java:138)
at org.apache.cxf.bus.extension.ExtensionManagerBus.<init>(ExtensionManagerBus.java:126)
at org.apache.cxf.bus.extension.ExtensionManagerBus.<init>(ExtensionManagerBus.java:138)
at org.apache.cxf.bus.spring.SpringBus.<init>(SpringBus.java:47)
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 org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:148)
... 46 more
Caused by: java.lang.IncompatibleClassChangeError: Implementing class
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:307)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
at org.apache.cxf.bus.extension.Extension.tryClass(Extension.java:169)
... 56 more

阅读java.lang.IncompatibleClassChangeError的原因是什么?它看起来像IncompatibleClassChangeError-意味着我的类路径上可能有冲突的库版本。我无法从堆栈跟踪中判断出哪个类/库正在被复制。

我的POM看起来是这样的:

<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<properties>
<wicket.version>1.5.11</wicket.version>
<spring.version>3.2.6.RELEASE</spring.version>
<project.build.sourceEncoding>windows-1252</project.build.sourceEncoding>
<netbeans.hint.deploy.server>Tomcat60</netbeans.hint.deploy.server>
<bootClassPath>
${env.JRE_6_HOME}librt.jar;${env.JAVA_HOME}libtools.jar;${env.JRE_6_HOME}libjsse.jar;
</bootClassPath>
<toolsDir>${env.JAVA_HOME}lib</toolsDir>
<jsseDir>${env.JAVA_HOME}jrelib</jsseDir>
<m2Repository>${env.USERPROFILE}/.m2/repository</m2Repository>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.2</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-core</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-extensions</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-datetime</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-spring</artifactId>
<version>${wicket.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-expression</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- shared look/functionality -->
<dependency>
<groupId>us.ak.state.revenue.cssd</groupId>
<artifactId>myAlaska</artifactId>
<version>1.6.2</version>
<exclusions>
<exclusion>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-datetime</artifactId>
</exclusion>
<exclusion>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>us.ak.state.revenue.cssd</groupId>
<artifactId>doc</artifactId>
<version>1.6.2</version>
</dependency>
<!-- WICKET DEPENDENCIES -->
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-datetime</artifactId>
<version>${wicket.version}</version>
<exclusions>
<exclusion>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- JUNIT DEPENDENCY FOR TESTING -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
<!-- SPRING Testing -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
<!-- TODO: once unit tests work test if this should be test scoped -->
</dependency>
<!-- Make Sure CXF starts properly -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-config</artifactId>
<version>3.2.0.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.2.0.RELEASE</version>
</dependency>
<!-- Spring Transactional Support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.2</version>
</dependency>
<!-- LDAP Authentication -->
<dependency>
<groupId>com.novell.ldap</groupId>
<artifactId>jldap</artifactId>
<version>4.3</version>
</dependency>
<!-- PDF report Generation -->
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.0.4</version>
</dependency>
<!-- email -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.5.0-b01</version>
</dependency>
<dependency>
<groupId>com.sun</groupId>
<artifactId>jsse</artifactId>
<version>1.6.0_21</version>
<scope>system</scope>
<systemPath>${env.JRE_6_HOME}libjsse.jar</systemPath>
</dependency>
<!-- Mainframe/Broker -->
<dependency>
<groupId>com.softwareAG.entirex</groupId>
<artifactId>entirex-runtime</artifactId>
<version>9.5.1</version>
</dependency>
<!-- Unknown / Miscl -->
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>${project.build.sourceEncoding}</encoding>
<compilerArguments>
<bootclasspath>
${bootClassPath};
</bootclasspath>
<endorseddirs>
${m2Repository}/javax/xml/bind/jaxb-api/2.2.6/;${m2Repository}/org/apache/cxf/cxf-rt-frontend-jaxws/2.7.5/;${toolsDir};${jsseDir};
</endorseddirs>
</compilerArguments>
<compilerArgument> -Xlint:unchecked </compilerArgument>
<showDeprecation>true</showDeprecation>
<showWarnings>true</showWarnings>
<optimize>true</optimize>
<debug>true</debug>
</configuration>
</plugin>
<plugin>
<groupId>com.atlassian.maven.plugins</groupId>
<artifactId>maven-clover2-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<!-- License info removed -->
<excludes>
<exclude>**/SessionFactoryBean*.java</exclude>
</excludes>
<cloverDatabase>${project.basedir}/.clover/db</cloverDatabase>
</configuration>
<executions>
<execution>
<id>clover</id>
<phase>generate-sources</phase>
<goals>
<goal>instrument</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<!-- moves the test results outside of clover-->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.10</version>
<configuration>
<reportsDirectory>
${project.build.directory}/surefire-reports
</reportsDirectory>
</configuration>
</plugin>
</plugins>
</build>    
</project>

MyAlaska是另一个项目正在成功使用的共享库,
具有以下依赖项:

<!-- another shared jar sits here that pulls in Wicket,Look-feel stuff -->

<!-- ADFS attempt #2, this time with WS-Federation/SAML support -->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxws</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-hc</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.2.6</version>
</dependency>
<!--https WS stuff-->
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-security-sso-saml</artifactId>
<version>2.7.5</version>
</dependency>
<!-- specifically adds SAML/federation to the stack -->
<dependency>
<groupId>org.apache.cxf.fediz</groupId>
<artifactId>fediz-core</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf.fediz</groupId>
<artifactId>fediz-cxf</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.cxf.fediz</groupId>
<artifactId>fediz-spring</artifactId>
<version>1.1.0</version>
</dependency>
<!-- Spring Security integration-->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-web</artifactId>
<version>3.1.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.wicket</groupId>
<artifactId>wicket-spring</artifactId>
</dependency>
<!-- configuration update "magic" -->
<dependency>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<version>1.9</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.0.7.RELEASE</version>
<scope>test</scope>
</dependency>

如果你还在这里,谢谢你的阅读
我做错了什么
为什么CXF/Spring不能启动,我该如何修复它?

更新:
运行调试器后,出现问题的类似乎是:org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl
,它位于cxf-rt-ws-policy-2.7.5
据我所知,这是那个罐子的唯一位置,它只包含一次。

JHades更新
当我最初运行报告时,Log4J和Log4J的额外内容重叠JavaMail-1.5和geronimo-JavaMail_1.4_spec。我已经解决了这些用法。

报告结果:

>>>> Jar overlap report: 

Total number of classes with more than one version: 0 

Jhadesmvn dependency:tree -Ddetail=true都表明cxf-rt-ws-policy与其他cxf-jar版本一样,是2.7.5

所以我发现我的IDE intellij dea把我的构建搞砸了
我想既然我配置了maven,它就只是在引擎盖下运行纯maven
在我的IDE中,我为Axis2-1.6.0配置了一个已安装的目录,以便在我的maven依赖项之前使用。Axis-2是我的应用程序的旧版本遗留下来的,它包含许多依赖项的副本,包括名为Neethi的东西,我看到它在CXF中列出了其他地方作为此错误的潜在来源。

似乎正在加载的类org.apache.cxf.ws.policy.AssertionBuilderRegistryImpl的版本无效。

您可以使用这个命令(来自JHades,我制作的一个工具)检查WAR,看看是否有任何重复的类,请参阅这里的重复类报告:

java -jar jhades-standalone-report.jar path/to/war/webapp.war

报告应该给出这样的内容:

>>>> Jar overlap report:
poi-3.5-FINAL-20090928.jar overlaps with poi-3.7-20101029.jar - total overlapping classes: 990
xercesImpl-2.7.0.jar overlaps with xercesImpl-2.9.1.jar - total overlapping classes: 867
xalan-2.6.0.jar overlaps with xalan-2.7.1.jar - total overlapping classes: 711
bcel-5.2.jar overlaps with xalan-2.7.1.jar - total overlapping classes: 361
xml-apis-2.9.1.jar overlaps with xml-apis.jar - total overlapping classes: 301
jasperreports-applet-3.7.1.jar overlaps with jasperreports-javaflow-3.7.1.jar - total overlapping classes: 254
jasperreports-3.7.1.jar overlaps with jasperreports-applet-3.7.1.jar - total overlapping classes: 254
...
Total number of classes with more than one version: 6169

还可以查询类的所有版本和当前使用的版本的类路径:

System.out.println("All versions of AssertionBuilderRegistryImpl:" + getClass().getClassLoader().getResources("org/apache/cxf/ws/policy/AssertionBuilderRegistryImpl.class"));
System.out.println("Currently used version of AssertionBuilderRegistryImpl:" + getClass().getClassLoader().getResource("org/apache/cxf/ws/policy/AssertionBuilderRegistryImpl.class"));

有两种可能性:要么存在多个版本,要么只有一个是正确的。在这种情况下,排除maven中版本错误的jar。

如果只存在一个版本,那么它就是错误的版本,请使用mvn dependency:tree -Ddetail=true查找包含它的原因,并更新pom以加载正确的版本。

最新更新