July 24, 2014

LinkageError: loader attempted duplicate class definition for name - 1



I have encountered this error on a Spring 4.0.5 + Hibernate 3 or 4 application.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'FMDao' defined in file [D:\apache-tomcat-7.0.34\webapps\mwas\WEB-INF\classes\com\mwas\datalayer\dao\FMDao.class]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.mwas.datalayer.dao.FMDao]: Common causes of this problem include using a final class or a non-visible class; nested exception is
org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:547)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
.
.
.  
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.mwas.datalayer.dao.FMDao]: Common causes of this problem include using a final class or a non-visible class; nested exception is org.springframework.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:206)
at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:109)
at org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator.createProxy(AbstractAutoProxyCreator.java:494)  
.
.
.
at org.springframework.cglib.proxy.Enhancer.create(Enhancer.java:285)
at org.springframework.aop.framework.CglibAopProxy.createProxyClassAndInstance(CglibAopProxy.java:227)
at org.springframework.aop.framework.ObjenesisCglibAopProxy.createProxyClassAndInstance(ObjenesisCglibAopProxy.java:66)
at org.springframework.aop.framework.CglibAopProxy.getProxy(CglibAopProxy.java:202)
... 36 more
.
.
at org.springframework.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:219)
... 41 more
Caused by: java.lang.LinkageError: loader (instance of  org/apache/catalina/loader/WebappClassLoader): attempted  duplicate class definition for name: "com/mwas/datalayer/dao/FMDao$$EnhancerBySpringCGLIB$$41240c1b"
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
at java.lang.ClassLoader.defineClass(ClassLoader.java:615)


After a lot of trial & error, I found that in order to integrate Hibernate with Spring 4.0.5, the following needs to be done

1. Add spring-orm 4.0.5 in your classpath or pom.xml ( if you are using Maven)
2. Add hibernate-core for release 3 or 4 in classpath or pom.xml.
3. Add cglib-nodep 3.1 in classpath or pom.xml

These steps should take care of the dependencies for Spring +t Hibernate integration.

Now, define the LocalSessionFactoryBean & HibernateTransactionManager in your Sprinconfiguration xml based on the hibernate version you intend to use. for e.g. for Hibernate 3, define

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
.
.
</bean>
<bean id="transactionManager"
            class="org.springframework.orm.hibernate3.HibernateTransactionManager">
    <property name="sessionFactory" ref="sessionFactory"/>
 </bean>

I encountered this error on a DAO class, annotated by @Repository.  One important step I took  in order to fix this error was to make the class implement an interface. This is weird, huh b'coz as per Spring docs, from 3.2 version CGLIB aop proxy creation don't require the target class to implement an interface


Need to investigate this further!!!

No comments:

Post a Comment