dev@glassfish.java.net

Faulty persistence loading

From: Jerome Dochez <Jerome.Dochez_at_Sun.COM>
Date: Wed, 01 Feb 2006 17:32:32 -0800

Hi All

This will be a long email so bear with me...

Talking with Mitesh, I discovered that we process persistence units too
late in the application deployment/loading. The issue is that today, we
do the following :
    - open the archive
    - process Java EE annotations (non persistence ones)
    - load XML
    - optional step : deployment
    - load application in ejb container which trigger
            + load persistence units with a new classloader
(getNewEjbClassLoader API)
            + process @Entity entities
            + create a new classloader with the provided ClassTransformer
            + reload the enhanced application classes.
    - run the application.

This is incorrect because :
    1. we create 3 class loaders when loading
    2. the classloader that was used to populate the DOL is not the same
as the one used to load the classes in the container (3rd class loader)
which is an issue since on the DOL, we store information like the Method
object related to security artifacts and such...
    3. the classloader on the DOL is not reset hence we keep reference
to at least 2 classloaders during the lifetime of the application.
 
We got lucky up to now because most @Entity classes do not use other
Java EE annotations and this did not trigger failures but it is an
unacceptable assumption.

It seems to me we need to change the way persistence units are loaded in
the application server to the following :

    - open the archive
    - create a temp class loader
    - find all persistence units and initialize the PersistenceProvider
with each of them and get the ClassTransformer from the provider
    - initialize a new ClassLoader with the ClassTransformer to use from
now on
    - process Java EE annotations
    - load XML
    - (deployment)
    - load applications.

When there are no persistence units in the deployment artifact, we skip
2, 3 and 4

Sahoo/Mitesh : how would that impact the Java SE path ?

This way we create only 2 class loaders (one to load the unchanged
classes, one to load the bytecode enhanced ones) . More importantly. we
ensure that the class used by the Java EE annotation processor and
deployment are the *final* class as they will be run in the EJB container.

Also a number of APIs on the PersistenceProvider interface like
getManagedClassNames() could allow us to plug my annotation scanner
enhancement to avoid loading extra classes when we know they do not
contain interesting annotations. I can work this out with Sahoo and Mitesh.

Let me know if I missed anything.

Thanks, Jerome