Re: JPA and class enhancers

From: Bill Dudney (bdudne..pache.org)
Date: Mon Mar 27 2006 - 16:11:00 EST

  • Next message: Mike Kienenberger: "Re: RoR'ing Cayenne"

    Hi Andrus,

    >
    > Regarding the ClassTransformer... JPA ClassTransformer is there to
    > presumably hide the details of how the actual enhancement is done.
    > By itself it won't allow you to redefine the class in the
    > application ClassLoader, only in your own ClassLoader. Consider a
    > test case:
    >
    > Object object = query.getSingleResult();
    >
    > assertEquals("Test1", MyPersistentClass.class.getName(),
    > object.getClass().getName());
    > assertTrue("Test2", object instanceof MyPersistentClass);
    >
    > The first test succeeds, but the second one fails! Cause you'll be
    > checking against MyPersistentClass from the app ClassLoader, not
    > the enhanced MyPersistentClass from the JPA ClassLoader. Somehow we
    > need to make a ClassTransformer to be a "delegate" for the app
    > class loader to force the entire application to use the enhanced
    > version of the class. The only way I know of is the instrumentation
    > API.

    My understanding is that the ClassTransformer is going to be employed
    by the EntityManager to transform the classes before returning them
    to the runtime.

    Take a look at the comment on the bottom of page 148. The way I read
    that is the ClassTransformer will be given a chance to augment any
    class before making that class available to the runtime. My
    understanding is that things go something like this;

    Java EE Environment;
    1) Container loads the persistence.xml file into a
    PersistenceUnitInfo instance
    2) Container creates the EntityManagerFactory implementation and
    passes in the PersistenceUnitInfo
    3) EntityManagerFactory (cayenne impl) adds a ClassTransformer to the
    PersistenceUnitInfo
    4) Container gets classes that are augmented by the ClassTransformer

    JavaSE Environment;
    1) Application loads JPA stuff with
    Persistence.createEntityManagerFactory(String)
    2) JPA runtime parses the persistence.xml file associated with the
    named persistence unit
    3) JPA runtime creates the EntityManagerFactory implementation and
    passes in the PersistenceUnitInfo
    3) EntityManagerFactory (cayenne impl) adds a ClassTransformer to the
    PersistenceUnitInfo
    4) JPA runtime gets classes that are augmented by the ClassTransformer

    So either way the classes that are used by the application are
    augmented by the ClassTransformer. In other words the app class
    loader will not be getting at the classes directly but instead will
    be using the persistence unit's class loader.

    So if this is true both 'Test1' and 'Test2' will work.

    Thoughts?

    Bill Dudney
    MyFaces - http://myfaces.apache.org
    Cayenne - http://incubator.apache.org/projects/cayenne.html



    This archive was generated by hypermail 2.0.0 : Mon Mar 27 2006 - 16:11:55 EST