Re: JPA and class enhancers

From: Andrus Adamchik (andru..bjectstyle.org)
Date: Tue Mar 28 2006 - 01:55:29 EST

  • Next message: Andrus Adamchik: "Re: JPA and class enhancers"

    > app class loader will not be getting at the classes directly but
    > instead will be using the persistence unit's class loader.

    That's what I thought initially too. Only after trying to make it
    work with test cases I realized the problem. With hierarchical
    ClassLoaders, a ClassLoader can either load classes directly or get
    them from its parent, but not from a child or a peer loader. In Java
    EE you can tweak loader hierarchy at the container level (or register
    ClassTransformers with the custom app ClassLoader subclass), so this
    is not a problem. AFAIK in Java SE you can't, except by using
    instrumentation API.

    I hope I've overlooked something basic. So how about this. Since you
    and Jeff will be working on the enhancer shortly, let's postpone this
    discussion till we can test the enhancer. It would be great if
    someone can prove me wrong on that.

    Andrus

    On Mar 28, 2006, at 1:11 AM, Bill Dudney wrote:
    >> 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 : Tue Mar 28 2006 - 01:55:55 EST