]
Pietu Pohjalainen updated HHH-3078:
-----------------------------------
Attachment: hibernate-patch-over-3.3.1GA.patch
Here's a patch against Hibernate 3.3.1GA, which fixes this issue.
Problem with multiple classloaders and cglib proxy enhancement, e.g.
in the usual tomcat configuration
------------------------------------------------------------------------------------------------------
Key: HHH-3078
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-3078
Project: Hibernate Core
Issue Type: Bug
Components: build
Affects Versions: 3.1.3, 3.2.5
Environment: Verified against Hibernate 3.1.3 and Hibernate 3.2.5ga.
Reporter: Pietu Pohjalainen
Attachments: hibernate-3.2.patch, hibernate-patch-over-3.3.1GA.patch,
LoadOrderTest.tar.gz
In an usual tomcat classloader configuration, with hibernate3.jar residing in the
Tomcat's common class loader and webapplications staying in their own classloaders,
the cglib's proxy enhancement fails sometimes, as it tries to load the web
application's classes via the Tomcat's common class loader.
The main culprit is the interaction between Hibernate's PojoEntityTuplizer and
cglib's AbstractClassGenerator.
PojoEntityTuplizer passes a Set of interfaces to cglib for proxy enhancement. The set is
constructed in method buildProxyFactory(PersistentClass, Getter, Setter). Now, depending
on the interface classes hash codes, the order of included interfaces varies: sometimes
Hibernate's HibernateProxy.class is the first one, sometimes it is the enhanced
interface's class.
Problems rise when the Set's iterator gives the interfaces in order of
{HibernateProxy.class, InterfaceToBeEnhanced.class}. When performing the enhancing, the
cglib chooses the first interface class's classloader to find all the other classes as
well. Because HibernateProxy.class was loaded by Tomcat's common class loader, it
cannot find the application's class InterfaceToBeEnhanced. Thus a
ClassDefNotFoundError is thrown.
There's a JUnit test demonstrating the case. Because the hashCodes of loaded classes
is quite undeterministic (read: beyond my skills to make deterministic), I've included
ten interface classes that should be cglib-enhanced. Most often, one of these enhancements
fails, due to this bug.
A fix would be to change hibernate to prioritize the application's interface classes
over Hibernate's HibernateProxy.class in the set. This could be implemented by using
LinkedHashSet instead of HashSet, and adding the HibernateProxy.class as the last one.
This change does not introduce any faults to existing unit test sets, but allows the
attaches JUnit test to run without failures. The attached patch is for Hibernate 3.2.5ga.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: