ConnectionWrapper is not visible from class loader

Description

Hibernate/Spring libraries are in app.war/WEB-INF/lib.
Timer is configured as resources in Tomcat and his libraries are in $CATALINA_HOME/common/lib/.

Function call from GUI works, but the same function called by timers gives this exception :

org.springframework.transaction.CannotCreateTransactionException: Could not openHibernate Session for transaction; nested exception is java.lang.IllegalArgumentException:
interface org.hibernate.jdbc.ConnectionWrapper is not visible from class loader
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:599)
....
Caused by: java.lang.IllegalArgumentException: interface org.hibernate.jdbc.ConnectionWrapper is not visible from class loader
at java.lang.reflect.Proxy.getProxyClass(Proxy.java:353)
at java.lang.reflect.Proxy.newProxyInstance(Proxy.java:581)
at org.hibernate.jdbc.BorrowedConnectionProxy.generateProxy(BorrowedConnectionProxy.java:67)
at org.hibernate.jdbc.ConnectionManager.borrowConnection(ConnectionManager.java:163)
at org.hibernate.jdbc.JDBCContext.borrowConnection(JDBCContext.java:111)
at org.hibernate.impl.SessionImpl.connection(SessionImpl.java:359)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doBegin(HibernateTransactionManager.java:510)

It's the same bug as was in HHH-2215, but this is not resolved.

I think, that the problem is extracting classloader from currentThread(). This is always not null, so the next test in method getProxyClassLoader() is always false.

I my case, timer thread lives in top class loader, but hibernate libraries are inside application class loader.
Attached patch removes classloader extracting from currentThread(). It works for my case.

Environment

SpringFramework 2.5.5, Hibernate 3.2.6 / 3.3.1, Tomcat 5.5, CommonJ Timer ( http://www.myfoo.de/commonj/ )

Activity

Show:
Steve Ebersole
March 21, 2011, 7:06 PM

Bulk closing stale resolved issues

Bjorn Harvold
November 5, 2009, 9:51 AM

FIXED. AWESOME!!!!

Steve Ebersole
November 5, 2009, 1:45 AM

The reason for the context classloader is that I am nervous about visibility of the generated proxy if we use the classloader for BorrowedConnectionProvider. Specifically of concern is that we would not be able to use this proxy (necessarily) anywhere the Connection interface itself would be valid. Can any of y'all verify this?

This class should be going away anyway, so maybe not such a big deal.

Vladimir Kralik
August 12, 2009, 2:17 PM

> How to use this pathc? appreciate if some can can share the steps..
Download source code for hibernate.
Then
mkdir hibernate-src/
cd hibernate-src/
tar xvfz hibernate-src-X.Y.Z.tar.gz
cd hiber*
patch -p1<hibernate-3.2.6_p2.patch
A now you can build hibernate library.

That patch contains change only in one class, so you can change it directly in Eclipse ( or another IDE )
First you have to setup hibernate project in Eclipse.
Then you find class BorrowedConnectionProxy, rid off all lines in patch which starts with dash and instead that lines put there line marked with plus , so the result will be

public static ClassLoader getProxyClassLoader() {
return BorrowedConnectionProxy.class.getClassLoader();
}

After compilation you should replace BorrowedConnectionProxy.class in orinal hibernate-X.Y.Z.jar.

HugoH
July 27, 2009, 11:25 AM

You have to build hibernate from svn source. However, unfornately you will have to maintain this fork of hibernate in your enterprise repository until it is fixed by hibernate itself.

Otherwise you can try an AOP solution and change the class loader before the call to the service, this is not an elegant solution but you don't have to maintain a hibernate patch.

Fixed

Assignee

Steve Ebersole

Reporter

Vladimir Kralik

Fix versions