persistence@glassfish.java.net

Need for a releaseTemporaryClassLoader method

From: Sanjeeb Kumar Sahoo <Sanjeeb.Sahoo_at_Sun.COM>
Date: Thu, 02 Mar 2006 23:43:41 +0530

Hi Mike,

By default Sun JDK use some kind of URL
caching(http://java.sun.com/j2se/1.5.0/docs/api/java/net/URLConnection.html#getDefaultUseCaches()).
On Windows platform this leads to jar file *locking*. What we have
observed is that once a URLClassLoader loads a resource from a jar file,
even after the class loader is garbage collected, the jar file can not
be deleted. It can only be deleted after JVM exits. This affects
redeployment of applications on Windows platform.
In our app server, we use a special ClassLoader which uses some work
around to avoid this issue. We create special URLStreamHandler which by
passes this caching and we also have a special clean up method in our
custom ClassLoader class that closes all the streams etc. We rely on
container to call this clean up method.

The temporary class loader introduced in persistence spec is causing
some problems. There is only a getNewTemporaryClassLoader() method
(https://glassfish.dev.java.net/source/browse/*checkout*/glassfish/persistence-api/src/java/javax/persistence/spi/PersistenceUnitInfo.java?rev=1.3)
which returns a java.lang.ClassLoader to the provider. There is no
release method which provider can use to signal the container to release
the class loader. So even if we give out a special class loader as
temporary class loader, in the absence of such a release method,
container is not able to call the clean up method.

There are ways to work around this, but we are of the opinion that a
*simple* change in the spec can lead to *simpler* implementation. There
are at least a couple of ways to do this:

1. Change the scope of temporary class loader. Make it such that the
temporary class loader is only usable inside
PersistenceProvider.createContainerEntityManagerFactory() call (I don't
see any reason why a provider would be using temporary class loader
after EMF creation). Allow container to hold a strong reference to the
class loader. That way after
PersistenceProvider.createContainerEntityManagerFactory() returns,
container can call appropriate clean up method of class loader.
OR
2. Add a method in PersistenceUnitInfo (say)
releaseTemporaryClassLoader(ClassLoader cl) which provider is must call
for every getNewTemporaryClassLoader() call.

I would be interested in knowing your opinion on this.

Thanks,
Sahoo