I just committed the code to enable runtime enhancement of JPA entities. The code makes use of the java instrumentation APIs[1] to hook all class loading. The gives us direct access to hook all class loading in the vm and to modify the java byte code for the class before it is loaded into memory. I have a few notes on the the instrumentation APIs so hopefully others will be able to support this code :)

* To use the instrumentation API, our java agent *must* be specified on the command line. I have added this to the standalone startup shell scripts. Without the agent we cannot enhance classes and pre- enhancement must be used [2]. Embedded servers (Tomcat and JUnit) must load the java agent or pre-enhance
   java -javaagent:$OPENEJB_JAVAAGENT_JAR -jar $OPENEJB_CORE_JAR start

* It is critical that application classes not be loaded before the Assembler. Code that runs before the Assembler, such as the Verifier, should use the TemporaryClassLoader. The TemporaryClassLoader loads all locally (even those found in parent class loaders), which means it doesn't pollute the parent class loader. (I forked this code from OpenJPA. thanks guys)

* A javaagent works much like an executable jar in that you specify a Premain-Class and Boot-Class-Path in the javaagent jar manifest. One big problem is that the premain class can not be debugged (at least in IntelliJ). It appears that the premain is executed before the debugger starts.

* Once you have a javaagent it is very easy to use ASM to modify a class. There is an example ClassFileTransformer in the JpaTest that adds a new field to a class at runtime[3].

That is all I can think of now :)

-dain

[1] http://java.sun.com/j2se/1.5.0/docs/api/java/lang/instrument/ package-summary.html
[2] http://cwiki.apache.org/openjpa/enhancingwithmaven.html
[3] http://svn.apache.org/viewvc/incubator/openejb/trunk/openejb3/ container/openejb-core/src/test/java/org/apache/openejb/core/cmp/jpa/ JpaTest.java?view=markup&pathrev=491149

Reply via email to