Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring core 3.2.2 + Spring security 3.1.4: java.lang.IncompatibleClassChangeError: org.springframework.asm.ClassVisitor

When I added Spring-security 3.1.4 next to Spring 3.2.2, I've got this ugly exception below. I googled it up and got only this link about the same error: http://forum.springsource.org/showthread.php?133706-Spring-3-2-0-RELEASE-breaks-with-JBoss-7 pointing to spring JIRA explaining that spring-asm is now in spring-core. https://jira.springsource.org/browse/SPR-10134

I figured I need to exclude spring-asm from spring-security somehow.

Here is the exception I had:

java.lang.IncompatibleClassChangeError: class org.springframework.core.LocalVariableTableParameterNameDiscoverer$ParameterNameDiscoveringVisitor has interface org.springframework.asm.ClassVisitor as super class
java.lang.ClassLoader.defineClass1(Native Method)
java.lang.ClassLoader.defineClass(ClassLoader.java:791)
java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
org.apache.catalina.loader.WebappClassLoader.findClassInternal(WebappClassLoader.java:2895)
org.apache.catalina.loader.WebappClassLoader.findClass(WebappClassLoader.java:1173)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1681)
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
org.springframework.core.LocalVariableTableParameterNameDiscoverer.inspectClass(LocalVariableTableParameterNameDiscoverer.java:112)
org.springframework.core.LocalVariableTableParameterNameDiscoverer.getParameterNames(LocalVariableTableParameterNameDiscoverer.java:85)
org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:193)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1051)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:955)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:651)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:599)
org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:665)
org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:518)
org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:459)
org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136)
javax.servlet.GenericServlet.init(GenericServlet.java:160)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1008)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
java.lang.Thread.run(Thread.java:722)
like image 622
Mano Kovacs Avatar asked May 28 '13 21:05

Mano Kovacs


2 Answers

Then I found this: http://www.mkyong.com/mongodb/spring-asm-dependency-issue-in-spring-data/ with a similar problem in spring-data. The exclusion in the pom.xml works just as well:

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-web</artifactId>
        <version>3.1.4.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework</groupId>
                <artifactId>spring-asm</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

I share the solution for others who get the same error!

like image 113
Mano Kovacs Avatar answered Nov 15 '22 12:11

Mano Kovacs


The problem is that Spring Security 3.1.4 depends on Spring 3.0.7, so it ends up pulling in spring-aop 3.0.7, which pulls in spring-asm 3.0.7. What you want to do is to use maven's dependencyManagement section to force any Spring inclusions to use the latest version, like so:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <!-- etc... 
          -- enumerate all Spring sub-projects here that spring-security includes 
          -->
        </dependency>
    </dependencies>
</dependencyManagement>

You can verify that you've managed away all the dependencies by running mvn dependency:tree.

For example, before dependencyManagement, my mvn dependency:tree output was:

[INFO] +- org.springframework.security:spring-security-core:jar:3.1.4.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:3.0.7.RELEASE:compile
[INFO] |  |  \- org.springframework:spring-asm:jar:3.0.7.RELEASE:compile
[INFO] |  +- org.springframework:spring-core:jar:3.2.3.RELEASE:compile (version managed from 3.0.7.RELEASE)
[INFO] |  +- org.springframework:spring-context:jar:3.0.7.RELEASE:compile
[INFO] |  +- org.springframework:spring-beans:jar:3.0.7.RELEASE:compile
[INFO] |  \- org.springframework:spring-expression:jar:3.0.7.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-config:jar:3.1.4.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-web:jar:3.1.4.RELEASE:compile
[INFO] |  +- org.springframework:spring-jdbc:jar:3.0.7.RELEASE:compile
[INFO] |  +- org.springframework:spring-web:jar:3.0.7.RELEASE:compile
[INFO] |  \- org.springframework:spring-tx:jar:3.0.7.RELEASE:compile

Notice in particular the first three lines, where spring-aop brings in spring-asm. After adding sufficient dependencyManagement declarations, we now get:

[INFO] +- org.springframework.security:spring-security-core:jar:3.1.4.RELEASE:compile
[INFO] |  +- org.springframework:spring-aop:jar:3.2.3.RELEASE:compile (version managed from 3.0.7.RELEASE)
[INFO] |  +- org.springframework:spring-core:jar:3.2.3.RELEASE:compile (version managed from 3.0.7.RELEASE)
[INFO] |  +- org.springframework:spring-context:jar:3.2.3.RELEASE:compile (version managed from 3.0.7.RELEASE)
[INFO] |  +- org.springframework:spring-beans:jar:3.2.3.RELEASE:compile (version managed from 3.0.7.RELEASE)
[INFO] |  \- org.springframework:spring-expression:jar:3.2.3.RELEASE:compile (version managed from 3.0.7.RELEASE)
[INFO] +- org.springframework.security:spring-security-config:jar:3.1.4.RELEASE:compile
[INFO] +- org.springframework.security:spring-security-web:jar:3.1.4.RELEASE:compile
[INFO] |  +- org.springframework:spring-jdbc:jar:3.2.3.RELEASE:compile (version managed from 3.0.7.RELEASE)
[INFO] |  +- org.springframework:spring-web:jar:3.2.3.RELEASE:compile (version managed from 3.0.7.RELEASE)
[INFO] |  \- org.springframework:spring-tx:jar:3.2.3.RELEASE:compile (version managed from 3.0.7.RELEASE)

Notice how spring-asm is not even included anymore, since the new spring-aop does not require it.

This is a cleaner way to manage your Spring versions than the exclusions in the answer above, as it will apply to any other 3rd party dependencies you might add that reference Spring.

like image 43
Astral Avatar answered Nov 15 '22 12:11

Astral