Hey Andrus,
You were of course right ;-)
I was sure there was an easy way to make it work because I could run
the test with Hibernate and it worked fine. But as I looked into the
internals of Hibernate its not actually instrumenting any classes for
this test case. I played around a bit and could not get it to
instrument anything so I decided to move on.
I'll continue to assume a managed env until I can get something
going. And then I'll come back to the non-managed env.
TTFN,
Bill Dudney
MyFaces - http://myfaces.apache.org
Cayenne - http://incubator.apache.org/projects/cayenne.html
On Mar 28, 2006, at 12:05 AM, Andrus Adamchik wrote:
> I suggested to postpone the discussion, but here is one more
> note :-) Let me clarify - I understand how JPA runtime can get
> access to enhanced classes. The problem is that the same class can
> also be accessed directly in the application, bypassing JPA runtime
> (just like in my unit test) - that's what causes the problem.
>
> Andrus
>
>
>
> On Mar 28, 2006, at 10:55 AM, Andrus Adamchik wrote:
>>> 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 : Wed Mar 29 2006 - 15:42:01 EST