5.2. Enhancement

In order to provide optimal runtime performance, flexible lazy loading,
and efficient, immediate dirty tracking, Kodo uses an
enhancer. An enhancer is a tool that automatically adds
code to your persistent classes after you have written them.
The enhancer post-processes the bytecode generated by your Java
compiler, adding the necessary fields and methods to implement the
required persistence features. This bytecode modification perfectly
preserves the line numbers in stack traces and is compatible with Java
debuggers.
In fact, the only change to debugging is that the persistent setter
and getter methods of entity classes using property access will be
prefixed with pc in stack traces and
step-throughs.
For example, if your entity has a getId method
for persistent property id, and that method throws
an exception, the stack trace will report the exception from method
pcgetId. The line numbers, however, will
correctly correspond to the getId method
in your source file.

You can add the Kodo enhancer to your build process,
or use Java 1.5's new instrumentation features to transparently enhance
persistent classes when they are loaded into the JVM. The following
sections describe each option.

5.2.1. Enhancing at Build Time

The enhancer can be invoked at build time via the
included kodoc script or via its Java class,
kodo.enhance.PCEnhancer.

-directory/-d <output directory>:
Path to the output directory. If the directory does not
match the enhanced class' package, the package structure
will be created beneath the directory. By default, the
enhancer overwrites the original .class
file.

-enforcePropertyRestrictions/-epr <true/t |
false/f>: Whether to throw an exception when
it appears that a property access entity is not obeying the
restrictions placed on property access. Defaults to false.

-addDefaultConstructor/-adc <true/t
| false/f>: The spec requires that all
persistent classes define a no-arg constructor. This flag
tells the enhancer whether to add a protected no-arg
constructor to any persistent classes that don't already
have one. Defaults to true.

-tmpClassLoader/-tcl <true/t
| false/f>: Whether to load persistent classes
with a temporary class loader. This allows other code to
then load the enhanced version of the class within the same
JVM. Defaults to true. Try setting
this flag to false as a debugging step
if you run into class loading problems when running the
enhancer.

Each additional argument to the enhancer must be one of the
following:

The full name of a class.

The .java file for a class.

The .class file of a class.

A .jdo metadata file. The enhancer
will run on each class listed in the metadata.

If you have not specified
a persistent class list, the enhancer will scan your classpath for
directories containing .jdo files, and run on
all classes listed in those files.

You can run the enhancer over classes that have already been
enhanced, in which case it will not further modify the class. You
can also run it over classes that are not persistence-capable, in
which case it will treat the class as persistence-aware.
Persistence-aware classes can directly manipulate the persistent
fields of persistence-capable classes.

Note that the enhancement process for subclasses introduces
dependencies on the persistent parent class being enhanced. This
is normally not problematic; however, when running the enhancer
multiple times over a subclass whose parent class is not yet
enhanced, class loading errors can occur. In the event of a class
load error, simply re-compile and re-enhance the offending classes.

5.2.2. Enhancing JPA Entities on Deployment

The JEE 5 specification includes hooks to automatically enhance
JPA entities when they are deployed into a container. Thus, if you
are using a JEE 5-compliant application server, Kodo will enhance
your entities automatically at runtime. Note that if you prefer
build-time enhancement, Kodo's runtime enhancer will correctly
recognize and skip pre-enhanced classes.

If your application server does not support the JEE 5 enhancement
hooks, consider using the build-time enhancement described above,
or the more general runtime enhancement described in the next
section.

5.2.3. Enhancing at Runtime

Kodo includes a Java agent for automatically
enhancing persistent classes as they are loaded into the JVM.
Java agents are classes that are invoked prior to your application's
main method. Kodo's agent uses JVM
hooks to intercept all class loading to enhance classes that
have persistence metadata before the JVM loads them.

Searching for metadata for every class loaded by the JVM can slow
application initialization. One way to speed things up is to
take advantage of the optional persistent class list described in
Section 5.1, “Persistent Class List”. If you declare a
persistent class list, Kodo will only search for metadata for
classes in that list.

To employ the Kodo agent, invoke java with the
-javaagent set to the path to your
openjpa.jar file.

scanDevPath: Boolean indicating whether
to scan the classpath for persistent types if none have
been configured. If you do not specify a persistent types
list and do not set this option to true, Kodo will check
whether each class loaded into the JVM is persistent, and
enhance it accordingly. This may slow down class load times
significantly.

5.2.4. Serializing Enhanced Types

By default, Kodo maintains serialization compatibility
between the enhanced and unenhanced versions of a class. This
allows you to serialize instances between a server using Kodo and
a client that does not have access to enhanced classes or Kodo
libraries. In some cases, however, you can make the persist and
attach processes more robust and efficient by allowing breaks in
serialization compatibility. See
Section 11.1.3, “Defining the Detached Object Graph” for details.