[hibernate-issues] [Hibernate-JIRA] Updated: (HHH-5962) Custom POJO Loading strategy for cglib and javassist

Ilya Samartsev (JIRA) noreply at atlassian.com
Fri Feb 25 07:18:08 EST 2011


     [ http://opensource.atlassian.com/projects/hibernate/browse/HHH-5962?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Ilya Samartsev updated HHH-5962:
--------------------------------

    Attachment: custom_class_loader-hibernate.patch

patch for Hibernate-3.6.1-Final

> Custom POJO Loading strategy for cglib and javassist
> ----------------------------------------------------
>
>                 Key: HHH-5962
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HHH-5962
>             Project: Hibernate Core
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 3.6.1
>         Environment: Hibernate 3.6.1, PostgreSQL, OSGi
>            Reporter: Ilya Samartsev
>         Attachments: custom_class_loader-hibernate.patch
>
>   Original Estimate: 40h
>  Remaining Estimate: 40h
>
> I use hibernate in OSGi-enabled environment and have found a strange class-loading behaviour of the initializer proxies. The problem is that it's not possible to define simple domain-model OSGi bundles which have pojo-based classes to be enhanced by hibernate without importing org.hibernate.*, net.sf.cglib.proxy.*, javassist.util.proxy.*, etc.
> Testing environment:
>  - A Model bundle with pojos and hibernate HBMs(they used by osgi-hibernate loader to enhance them). This bundle doesn't actually require any hibernate/cglib/javassist imports for the reason there are simple pojos in it.
>   /src/com/example/TestPojoModel.java
>   /META-INF/mappings/TestPojoModel.hbm.xml
>   /META-INF/MANIFEST.MF
> Expected behaviour:
> To have "clean" bundle with pojos without any additional imports(e.g. org.hibernate.* or cglib/javassist).
> Enhance these classes without any errors.
> Current behaviour:
> These pojo-based model bundles require to import a lot of hibernate and cglib or javassist stuff to enhance these pojos. The problem is that hibernate uses the same classloader (from model bundle) to load both pojos and hibernate/codegeneration utility classes. Otherwise it crushes with ClassNotFoundException.
> Code explanation:
> Javassist ProxyFactory initialization:
>  org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer:
>     ProxyFactory factory = new ProxyFactory();
>     factory.setSuperclass( interfaces.length == 1 ? persistentClass : null );
>     factory.setInterfaces( interfaces );
>     factory.setFilter( FINALIZE_FILTER );
>     return factory.createClass();
> How javassist loads classes by default:
>  javassist.util.proxy.ProxyFactory:
>     protected ClassLoader getClassLoader0() {
>       ClassLoader loader = null;
>       if (superClass != null && !superClass.getName().equals("java.lang.Object"))
>         loader = superClass.getClassLoader();
>       else if (interfaces != null && interfaces.length > 0)
>         ...
>       }
>       return loader;
> }
> It actually uses the classloader of the persistent class. 
> My proposition:
> To create advanced classloader for ProxyFactory which has custom behaviour:
> 1. Firstly it tries to load class using the classloader of the persistent class
> 2. Secondly it tries to use the classloader of the curent hibernate bundle (which definitely has access to its own hibernate classes and imports the classes of the codegeneration libraries)
> final ClassLoader platformDelegatingClassLoader = new ClassLoader(persistentClass.getClassLoader()) {
>   private final ClassLoader platformClassLoader = getClass().getClassLoader();
>   // on loadClass() it tries to use parent's classloader(parent = persistentClass.getClassLoader() - from the constructor)
>   // if loadClass() didn't find class it tries to findClass() which is actually overridden to use current context's getClass().getClassLoader()
>   @Override
>   protected Class<?> findClass(String name) throws ClassNotFoundException {
>     return platformClassLoader.loadClass(name);
>   }
> };
> ProxyFactory factory = new ProxyFactory() {
>   @Override
>   protected ClassLoader getClassLoader() {
>     return platformDelegatingClassLoader;
>   }
> };

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://opensource.atlassian.com/projects/hibernate/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list