Hi,
In my application I am loading plug-ins mapping documents and persistent classes from jars using some UrlClassLoaders (one per plugin). I then set the threadContextClassLoader to be the CompositeClassLoader that holds all those UrlClassLoaders. Everything works fine until I add a proxy to one of the mapping document (I simplified the names a little):
Code:
<hibernate-mapping>
<subclass
name="myplugin.MyExtension"
discriminator-value="3"
[b]proxy="myplugin.IMyExtension"[/b]
extends="core.MyBasicClass"
>
<join table="MY_EXTENSION">
<key column="ENTITY_ID"/>
<property name="extraNumData" column="EXTRA_NUM_DATA" type="long"/>
<property name="extraStrData" column="EXTRA_STR_DATA" type="string"/>
</join>
</subclass >
</hibernate-mapping>
See below the exception I get (along with other details).
Hibernate uses net.sf.cglib.proxy.Enhancer as the class generator in CGLIBLazyInitializer.getProxyFactory(). Now, it seeme like CGLIB
allows customizing the ClassLoader used by its class generators using the method net.sf.cglib.core.AbstractClassGenerator.setClassLoader() (Enhancer extends AbstractClassGenerator). But, it doesn't seem like it is possible to use it in Hibernate, because this is how the Enhancer is used in CGLIBLazyInitializer.getProxyFactory() :
Code:
return (Factory) Enhancer.create(
(interfaces.length==1) ? persistentClass : null,
interfaces,
NULL_METHOD_INTERCEPTOR
);
If I replace it with the following code, it works:
Code:
Enhancer e = new Enhancer();
e.setSuperclass((interfaces.length==1) ? persistentClass : null);
e.setInterfaces(interfaces);
e.setCallback(NULL_METHOD_INTERCEPTOR);
e.setClassLoader(Thread.currentThread().getContextClassLoader()); // this is the addition!
return (Factory)e.create();
Is there any other way I can do it (I know I can implement my own persister, but it seems like there's too much code that needs to be overridden...)?
Is there any planned enhancement regarding this issue?
Thanks a lot!
Hibernate version: 3.0.5
Mapping documents: see above
Full stack trace of any exception that occurs:
CGLIB Enhancement failed: com.octavian.fas.domain.business.BusinessTransaction
net.sf.cglib.core.CodeGenerationException: java.lang.reflect.InvocationTargetException-->null
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:236)
at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:373)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:281)
at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:640)
at org.hibernate.proxy.CGLIBLazyInitializer.getProxyFactory(CGLIBLazyInitializer.java:94)
at org.hibernate.proxy.CGLIBProxyFactory.postInstantiate(CGLIBProxyFactory.java:42)
at org.hibernate.tuple.PojoTuplizer.buildProxyFactory(PojoTuplizer.java:144)
at org.hibernate.tuple.AbstractTuplizer.<init>(AbstractTuplizer.java:83)
at org.hibernate.tuple.PojoTuplizer.<init>(PojoTuplizer.java:54)
at org.hibernate.tuple.TuplizerLookup.create(TuplizerLookup.java:47)
at org.hibernate.tuple.EntityMetamodel.<init>(EntityMetamodel.java:218)
at org.hibernate.persister.entity.BasicEntityPersister.<init>(BasicEntityPersister.java:400)
at org.hibernate.persister.entity.SingleTableEntityPersister.<init>(SingleTableEntityPersister.java:104)
at org.hibernate.persister.PersisterFactory.createClassPersister(PersisterFactory.java:55)
at org.hibernate.impl.SessionFactoryImpl.<init>(SessionFactoryImpl.java:211)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1005)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.newSessionFactory(LocalSessionFactoryBean.java:777)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:703)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1058)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:363)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:226)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:147)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:269)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:318)
at com.octavian.sma.analytical.batch.SpringHelper.init(SpringHelper.java:77)
at com.octavian.sma.analytical.batch.SpringHelper.<init>(SpringHelper.java:38)
at com.octavian.sma.analytical.batch.dailynongrouping.DailyNonGroupingAnalyticalBatch.initSpringHelper(DailyNonGroupingAnalyticalBatch.java:44)
at com.octavian.sma.analytical.batch.AnalyticalBatch.run(AnalyticalBatch.java:58)
at com.octavian.sma.analytical.batch.dailynongrouping.DailyNonGroupingAnalyticalBatch.main(DailyNonGroupingAnalyticalBatch.java:29)
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor3.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at net.sf.cglib.core.ReflectUtils.defineClass(ReflectUtils.java:373)
at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:218)
... 28 more
Caused by: java.lang.NoClassDefFoundError: myplugin/IMyBusinessTransactionExtension
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:620)
... 33 more