使用Spring在jetty-maven-plugin中出现无法解释的IncompatibleClassChangeError

时间:2015-03-04 21:15:43

标签: java spring maven jetty maven-jetty-plugin

我正在研究Restlet应用程序问题,并认为设置一个包含要测试的应用程序的简化版本的Github存储库会很棒。但是,它从未如此简单......

存储库位于:https://github.com/morungos/restlet-spring-static-files

基本上,问题在于每当我尝试使用mvn jetty:run-war运行它时(我实际上需要做的是测试重定时问题),我得到以下回溯:

java.lang.IncompatibleClassChangeError: class org.springframework.cglib.core.DebuggingClassWriter has interface org.springframework.asm.ClassVisitor as super class
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:415)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:377)
at org.springframework.cglib.core.DefaultGeneratorStrategy.getClassVisitor(DefaultGeneratorStrategy.java:30)

有趣的部分是原始应用程序 - 即使我使用完全相同的pom.xml,也没有为同一命令显示相同的问题。 mvn jetty:run似乎都没问题,但Restlet问题需要一个war文件来测试。

现在我已经看到了这个问题,它通常是一个ASM / CGLIB冲突,当我检查依赖关系时,Jetty和Spring都使用不同的ASM系统,但我想知道在哪里或如何设置依赖关系做这个工作。即使我可以,我也无法弄清楚它为什么在一个应用程序中运行而不是在一个稍微小一点的版本中(遗憾的是我还没有显示)。

有关如何解决此问题的任何想法?我尝试在引起问题的Jetty依赖项中添加一个排除项(jetty-annotations)但是Jetty失败了,所以它显然是必需的。

2 个答案:

答案 0 :(得分:1)

我使用mvn dependency:tree看了你的pom。你有Spring 3.2和3.1 JAR的混合。 Restlet正在引入Spring 3.2 JAR。

[INFO] +- org.restlet.jee:org.restlet:jar:2.3.1:compile
[INFO] +- org.restlet.jee:org.restlet.ext.servlet:jar:2.3.1:compile
[INFO] +- org.restlet.jee:org.restlet.ext.spring:jar:2.3.1:compile
[INFO] |  +- cglib:cglib-nodep:jar:2.2:compile
[INFO] |  +- commons-logging:commons-logging:jar:1.1.3:compile
[INFO] |  +- org.springframework:spring-beans:jar:3.2.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-core:jar:3.2.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-expression:jar:3.2.6.RELEASE:compile
[INFO] |  +- org.springframework:spring-web:jar:3.2.6.RELEASE:compile
[INFO] |  |  \- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  \- org.springframework:spring-webmvc:jar:3.2.6.RELEASE:compile
[INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:compile
[INFO] +- org.springframework:spring-context:jar:3.1.4.RELEASE:runtime
[INFO] |  +- org.springframework:spring-aop:jar:3.1.4.RELEASE:compile
[INFO] |  \- org.springframework:spring-asm:jar:3.1.4.RELEASE:compile
[INFO] +- org.slf4j:slf4j-api:jar:1.7.7:compile
[INFO] +- org.slf4j:slf4j-jdk14:jar:1.7.7:compile
[INFO] \- junit:junit:jar:4.9:test
[INFO]    \- org.hamcrest:hamcrest-core:jar:1.1:test

答案 1 :(得分:0)

嗯,我不小心让Spring和Restlets解决他们的分歧。明确地引入所有Spring依赖项,而不仅仅是我需要的几个依赖项,完全不同。春天的runtime范围也在悄悄进入。

我所做的只是将以下顶级依赖项添加到POM中:

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

当我小心翼翼地回去时,我可以看到应用程序引入版本3.1.4和3.2.6,并混合它们。令人惊讶的是,除了Jetty之外,一切似乎都能正常工作,并且只有在WAR上调用时才能正常工作。

组件之间的远程交互总是更难调试,我猜......