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