Sorry, got busy and missed this email.
This is such a common problem, it was addressed directly by the JPA
specs. When loading classes for inspection use the class loader
returned from
javax.persistence.spi.PersistenceUnitInfo.getNewTempClassLoader().
For Cayenne's own PersistenceUnitInfo implementation, I suggest you
copy org.apache.openejb.core.TemporaryClassLoader which I copied from
OpenJPA and cleaned up.
-dain
On Feb 20, 2007, at 4:31 AM, Andrus Adamchik wrote:
Dain Sundstrom (who is a member of Geronimo project) did some
preliminary testing of Cayenne JPA provider in the OpenEJB
container last week - you've seen some jiras that he opened. I am
taking further discussion to the list (not sure if Dain is
subscribed, so I am cc'ying to him as well).
So the enhancer... I tried to run the OpenEJB JpaTest [1] with
Cayenne provider. It fails to enhance the Employee object [2], even
if it is explicitly mentioned in the PersistenceUnit, because it
was loaded in the JVM *before* Cayenne provider was started and
Provider.createContainerEntityManagerFactory(..) was called.
I was trying to think of ways to "fix" it, but considering that
java.lang.instrument.Instrumentation doesn't allow to enhance
already loaded classes ("redefineClasses" method places serious
limitations on what can be done, namely adding new fields is not
allowed), looks like JPA users will have to deal with specific
startup order requirements. In-container and Java SE operation
modes will look different:
1. In-container: provider shouldn't directly access its own agent,
and simply register a needed ClassTransformer with container-
provided PersistenceUnitInfo. Container on the other hand has the
responsibility to hook up PersistenceUnitInfo implementor to the
agent, and ensure that provider is started *before* and persistence
classes are loaded in the app class loader. So I wonder whether the
fact that JpaTest worked with OpenJPA provider by some coincidence?
2. Standalone: for the enhancer to work, an application must ensure
a call to Persistence.createEntityManagerFactory() prior to the
entity classes loaded in runtime. This sucks, and the only way
around is to run enhancer straight from the agent. I think that's
what OpenJPA does. Some time ago we decided [3] to avoid putting
any Cayenne runtime classes in the agent, but it looks like we
don't have a choice. Unless somebody can suggest a better way of
providing reliable runtime enhancement, I will change the behavior
to provide a "fat" agent.
[1] https://svn.apache.org/repos/asf/incubator/openejb/trunk/
openejb3/container/openejb-core/src/test/java/org/apache/openejb/
core/cmp/jpa/JpaTest.java
[2] https://svn.apache.org/repos/asf/incubator/openejb/trunk/
openejb3/container/openejb-core/src/test/java/org/apache/openejb/
core/cmp/jpa/Employee.java
[3] http://objectstyle.org/cayenne/lists/cayenne-devel/
2006/08/0088.html
Andrus
P.S. Dain - are there any other show stopper issues in your testing
(except for no EJBQL)?