ASM version incompatibilities, using Spring @Autowired with Hibernate

I was working on Spring 2.1 stuff this week with Joris. We were preparing a sample using all three ways of doing dependency injection. The sample does not only highlight dependency injection, but also features a back-end based on Hibernate.
Several features in Spring 2.1 require the ASM byte code manipulation framework. Hibernate also uses ASM, through CGLIB. There is a binary incompatibility between ASM 1.5.3 and 2.2.3. The former is used by Hibernate, the latter is used by Spring in various scenarios; specifically in some of the AOP functionality and the new @Autowired features.
UPDATE: read solution number 3 first!
Solution no. 1
The first solution is to explicitly replace the CGLIB jar for Hibernate with a nodep version (one is available from the Spring distribution) which contains a re-packaged version of ASM version 1.5.3. With Maven, this requires you to put in a few exclusions alongside your Hibernate dependency and to explicitly put in the ASM 2.2.3 dependency in your pom.
<groupId>org.hibernate</groupId>
<artifactId>hibernate</artifactId>
<version>3.2.1.ga</version>
<exclusions>
<exclusion>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
</exclusion>
<exclusion>
<groupId>asm</groupId>
<artifactId>asm-attrs</artifactId>
</exclusion>
</exclusions>
</dependency>
<groupId>asm</groupId>
<artifactId>asm</artifactId>
<version>2.2.3</version>
</dependency>
Solution no. 2
I haven't tried this, but according to the Hibernate JIRA you can change the byte code provider for Hibernate to Javassist, as commented by Max Rydahl Andersen in the bug report.
Solution no.3 (added October 18 2007)
As of Spring 2.5rc1, spring.jar contains ASM 2.2.3 (repackaged using Jar Jar Links (that name!!!!!
). This means all incompatibilities with other projects using ASM should from now on be a thing of the past. I haven't tried this out yet, so you should figure this one out for yourself.
Modified

Corby Page says:
Added on June 11th, 2007 at 9:01 am -QuoteThanks for doing a prominent write-up on this. This issue has existed for a couple of years with the AOP stuff, and is always challenging for people who are hitting it for the first time.
Tetsuo says:
Added on June 11th, 2007 at 11:06 am -QuoteFor what I've seen in other projects, they usually create a fork with the specific version of ASM they use, and add it to their own codebase, probably to avoid this instability of the API. Why don't you do the same?
Bob Lee says:
Added on June 11th, 2007 at 11:25 am -QuoteGuice gets around this by using jarjar to repackage ASM inside of our jar at build time. That does suck that ASM broke backward compatibility like that. Why not create a new package named "asm2"?
Colin Sampaleanu (blog author) says:
Added on June 11th, 2007 at 5:18 pm -QuoteI was talking to Eugene Kuleshov (one of the ASM committers) about this, and he said that basically it's a given that ASM has to change on a regular basis to support new JDK features, so the expectation is in fact that you will basically fork a specific version into your package structure, ala cglib_nodep…
So this basically means that the idea of versioning ASM in a simple fashion with Maven, where 3.0 can replace 2.0, is completely unrealistic. It also means 2.0 and 3.0 can not live side by side. Realistically, unless you assume no other app/lib than yours will ever use ASM, it means you have to fork it into your own app/lib.
I don't really think this is a great strategy. I think it would have been realistic to change the base asm package each time it changed in an incompatible fashion. So we'd be up to ASM 33 by now, but so what?
softengg says:
Added on June 20th, 2007 at 4:53 am -QuoteHi,
I am having problems running a very basic JUnit test case via Maven2. The application uses spring-framework-2.1-m1 release, and test case extends from org.springframework.test.jpa.AbstractJpaTests, uses org.springframework.orm.jpa.LocalContainerEntityMa nagerFactoryBean as entityManagerFactory, and uses
org.springframework.orm.jpa.vendor.HibernateJpaVen dorAdapter as jpaVendorAdapter propery for entityManagerFactory. Complete issue is here http://forum.springframework.org/showthread.php?p=127012#poststop. I have tried your outlined solution, but the exception is same. Any help would be great!
Below are few lines from stack trace,
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/applicationContext-jpaCommon.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javassist.bytecode.ClassFile.getName()Ljava/lang/String;
Caused by: java.lang.NoSuchMethodError: javassist.bytecode.ClassFile.getName()Ljava/lang/String;
at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:652)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:350)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:126)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:218)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:251)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1201)
softengg says:
Added on June 20th, 2007 at 5:09 am -QuoteHi, i have tried soln # 1 but it does not resolve my problem. My detailed problem is here on spring forum http://forum.springframework.org/showthread.php?p=127012#poststop and someone from there refereed me here. Any help would be great!
On difference is that I had to include dependency on javaassist as I was getting error that its not inclasspath. After adding it get the exception (details on above URL, summary is here). Here are first few lines from the exception stack trace.
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [META-INF/applicationContext-jpaCommon.xml]: Invocation of init method failed; nested exception is java.lang.NoSuchMethodError: javassist.bytecode.ClassFile.getName()Ljava/lang/String;
Caused by: java.lang.NoSuchMethodError: javassist.bytecode.ClassFile.getName()Ljava/lang/String;
at org.hibernate.ejb.Ejb3Configuration.scanForClasses(Ejb3Configuration.java:652)
at org.hibernate.ejb.Ejb3Configuration.configure(Ejb3Configuration.java:350)
at org.hibernate.ejb.HibernatePersistence.createContainerEntityManagerFactory(HibernatePersistence.java:126)
at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:218)
at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:251)
Daniel says:
Added on October 25th, 2007 at 5:38 am -QuoteI tried solution No 1 but cglib (which is used by hibernate) uses old classes and methods from asm which are not present in asm-2.2.3. So i got an java.lang.NoClassDefFoundError: org/objectweb/asm/CodeVisitor from hibernate initialisation.
I solved this by using cglib-nodep-2.1_3 from maven repository, instead of cglib from the hibernate dependencies, see: http://mvnrepository.com/artifact/cglib/cglib-nodep/2.1_3
org.hibernate
hibernate
[3.2.2.ga]
asm
asm
asm
asm-attrs
cglib
cglib
cglib
cglib-nodep
2.1_3
cglib-nodep contains asm classes but they are in different packages as in the asm jars.
Daniel says:
Added on October 25th, 2007 at 5:40 am -QuoteHmm, you can not post XML here. Here is my XML code from the end of the posting:
[dependency]
[groupId]org.hibernate[/groupId]
[artifactId]hibernate[/artifactId]
[version][3.2.2.ga][/version]
[exclusions]
[exclusion]
[groupId]asm[/groupId]
[artifactId]asm[/artifactId]
[/exclusion]
[exclusion]
[groupId]asm[/groupId]
[artifactId]asm-attrs[/artifactId]
[/exclusion]
[exclusion]
[groupId]cglib[/groupId]
[artifactId]cglib[/artifactId]
[/exclusion]
[/exclusions]
[/dependency]
[dependency]
[groupId]cglib[/groupId]
[artifactId]cglib-nodep[/artifactId]
[version]2.1_3[/version]
[/dependency]
[dependency]
Josh Mahowald says:
Added on December 4th, 2007 at 4:03 pm -QuoteJust a FYI
Unfortunately, solution 3 won't work for me, and my guess would be most people, if you are using dynamic languages, as GroovyScriptFactory uses the GroovyClassLoader, which comes in a different jar (groovy jar of course), which still uses the old org.objectweb.asm pagkage, rather than the new spring org.springframework.asm package