> 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