![]() | ![]() |
![]() |
| Project | Ver 1.1 | Ver 1.2 | JDO | JPA | Guides | Tools |
| 1.1 | Preparation | O/R Mapping | Runtime | Extensions | Developer |
In a JDO-enabled application there are 3 categories of classes. These are PersistenceCapable, PersistenceAware and normal classes. The Meta-Data defines which classes fit into these categories. To give an example, we have 3 classes. The class A is to be persisted in the datastore. The class B directly updates the fields of class A but doesn't need persisting. The class C is not involved in the persistence process. We would define MetaData for these classes like this
<class name="A" persistence-modifier="persistence-capable">
<field name="myField">
...
</field>
...
</class>
<class name="B" persistence-modifier="persistence-aware">
</class>So our MetaData is mainly for those classes that are PersistenceCapable and are to be persisted to the datastore (we don't really need the persistence-modifier for thse classes since this is the default). For PersistenceAware classes we simply notate that the class knows about persistence. We don't define MetaData for any class that has no knowledge of persistence.
JDO requires that all classes to be persisted must implement the PersistenceCapable interface
![]() The example above doesn't show all PersistenceCapable methods, but demonstrates that all added methods and fields are prefixed with "jdo" to distinguish them from the users own methods and fields. Also each persistent field of the class will be given a jdoGetXXX, jdoSetXXX method so that accesses of these fields are intercepted so that JDO can manage their "dirty" state.
The MetaData defines which classes are required to be persisted, and also defines which aspects of persistence
each class requires. For example if a class has the detachable attribute set to true, then
that class will be enhanced to also implement Detachable
![]() Again, the example above doesn't show all methods added for the Detachable interface but the main thing to know is that the detached state (object id of the datastore object, the version of the datastore object when it was detached, and which fields were detached is stored in "jdoDetachedState"). Please see the JDO spec for more details. If the MetaData is changed in any way during development, the classes should always be recompiled and re-enhanced afterwards. How to use the JPOX Enhancer depends on what environment you are using. Below are some typical examples.
Some groups perpetuate arguments against "byte-code enhancement" saying that it is somehow 'evil'. The most common are :-
So as you can see, there are no valid reasons against byte-code enhancement, and the pluses are that runtime detection of dirty events on objects is much quicker, hence your persistence layer operates faster without any need for iterative reflection-based checks.
JPOX provides a JAR containing the Enhancer (jpox-enhancer.jar). If you are building your application manually and want to enhance your classes you follow the instructions in this section. You invoke the enhancer as follows
java -cp classpath org.jpox.enhancer.JPOXEnhancer [options] [jdo-files] [class-files]
where options can be
-d target-dir-name : Write the enhanced classes to the specified directory
-api api-name : Name of the API we are enhancing for (JDO, JPA)
-enhancerName name : Name of the ClassEnhancer to use (BCEL)
-checkonly : Just check the classes for enhancement status
-verify : Verify the classes
-v : verbose output
where classpath MUST contain the following
jpox-enhancer.jar
jpox.jar
bcel.jar
jdo2-api.jar
log4j.jar
your classes
your meta-data filesIf your classes have metadata files then you must provide them. If your classes use annotations then you just provide the class files. To give an example of how you would invoke the enhancer
Linux/Unix :
java -cp target/classes:lib/jpox-enhancer.jar:lib/jpox.jar:lib/jdo2-api.jar:lib/log4j.jar:lib/bcel.jar
-Dlog4j.configuration=file:log4j.properties
org.jpox.enhancer.JPOXEnhancer
**/*.jdo
Windows :
java -cp target\classes;lib\jpox-enhancer.jar;lib\jpox.jar;lib\jdo2-api.jar;lib\log4j.jar;lib\bcel.jar
-Dlog4j.configuration=file:log4j.properties
org.jpox.enhancer.JPOXEnhancer -v
target/classes/org/jpox/examples/inverse/package.jdo
target/classes/org/jpox/examples/normal/package.jdo
[should all be on same line. Shown like this for clarity]So you pass in your JDO MetaData files (and/or the class files wihich use annotations) as the final argument(s) in the list, and include the respective JAR's in the classpath (-cp). The enhancer responds as follows JPOX Enhancer (version 1.1.0) : Enhancement of classes JPOX Enhancer : Classpath >> /home/andy/work/JPOX/samples/packofcards/target/classes >> /home/andy/work/JPOX/samples/packofcards/lib/log4j.jar >> /home/andy/work/JPOX/samples/packofcards/lib/jdo2-api.jar >> /home/andy/work/JPOX/samples/packofcards/lib/jpox.jar >> /home/andy/work/JPOX/samples/packofcards/lib/jpox-enhancer.jar >> /home/andy/work/JPOX/samples/packofcards/lib/bcel.jar JPOX Enhancer : Input Files >> /home/andy/work/JPOX/samples/packofcards/target/classes/org/jpox/examples/inverse/package.jdo >> /home/andy/work/JPOX/samples/packofcards/target/classes/org/jpox/examples/normal/package.jdo Processing class "org.jpox.examples.inverse.Pack" ENHANCED: org.jpox.examples.inverse.Pack Processing class "org.jpox.examples.inverse.Card" ENHANCED: org.jpox.examples.inverse.Card Processing class "org.jpox.examples.normal.Pack" ENHANCED: org.jpox.examples.normal.Pack Processing class "org.jpox.examples.normal.Card" ENHANCED: org.jpox.examples.normal.Card If you have errors here relating to "Log4J" then you must fix these first. If you receive no output about which class was ENHANCED then you should look in the JPOX enhancer log for errors. The enhancer performs much error checking on the validity of the passed MetaData and the majority of errors are caught at this point. You can also use the JPOX Enhancer to check whether classes are enhanced. To invoke the enhancer in this mode you specify the checkonly flag. This will return a list of the classes, stating whether each class is enhanced for persistence under JDO or not. The classes need to be in the CLASSPATH (Please note that a CLASSPATH should contain a set of JAR's, and a set of directories. It should NOT explictly include class files, and should NOT include parts of the package names. If in doubt please consult a Java book).
Maven1 operates from a series of plugins. There is a JPOX plugin for Maven1 that allows enhancement of classes. Go to the Download section of the website and download this. Once you have the Maven1 plugin, you then need to set the properties for the plugin in your project.properties file. This will typically not require any addition to your project.properties. If you do need to change this file, the following parameters are the likely ones to change
maven.jpox.jdo.fileset.dir=${maven.build.dest} # Location of the JDO files
maven.jpox.jdo.fileset.include=**/*.jdo # fileset to include
#maven.jpox.jdo.fileset.exclude=something.jdo # fileset to exclude, if any
maven.jpox.classes.dir=${maven.build.dest} # Location of classes to enhance
maven.jpox.log4j.configuration= # Log definition to use
maven.jpox.verbose=true # Turn on more output ?You then run the Maven JPOX plugin, as follows maven jpox:enhance This will enhance all classes found that correspond to the classes defined in the JDO files in your source tree. If you want to check the current status of enhancement you can also type maven jpox:enhance-check
Maven2 operates from a series of plugins. There is a JPOX plugin for Maven2 that allows enhancement of classes. Go to the Download section of the website and download this. Once you have the Maven1 plugin, you then need to set the properties for the plugin in your project.properties file. This will typically not require any addition to your pom.xml. If you do need to change this file, the following parameters are the likely ones to change
Configuration name Default Value Description
mappingIncludes **/*.jdo Fileset to include
mappingExcludes Fileset to exclude, if any
log4jConfiguration {internal props} Log definition to use
verbose false Turn on more output ?You then run the Maven2 JPOX plugin, as follows mvn jpox:enhance This will enhance all classes found that correspond to the classes defined in the JDO files in your source tree. If you want to check the current status of enhancement you can also type mvn jpox:enhance-check Or alternatively, you could add the following to your POM
<build>
...
<plugins>
<plugin>
<groupId>jpox</groupId>
<artifactId>jpox-maven-plugin</artifactId>
<version>1.1.7</version>
<configuration>
<log4jConfiguration>${basedir}/log4j.properties</log4jConfiguration>
<verbose>true</verbose>
</configuration>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>enhance</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
...
</build>So you then get auto-enhancement after each compile
Ant provides a powerful framework for performing tasks. JPOX provides an Ant task to enhance classes. JPOX provides a JAR containing the Enhancer (jpox-enhancer.jar). You need to make sure that the jpox-enhancer.jar, jpox.jar, bcel.jar, log4j.jar and jdo2-api.jar are in your classpath. In the JPOX Enhancer Ant task, the following parameters are available
So you could define something like the following, setting up the parameters enhancer.classpath, jdo.file.dir, and log4j.config.file to suit your situation (the jdo.file.dir is a directory containing the JDO files defining the classes to be enhanced). The classes specified by the JDO Meta-Data files, together with the JDO Meta-Data files must be in the CLASSPATH (Please note that a CLASSPATH should contain a set of JAR's, and a set of directories. It should NOT explictly include class files, and should NOT include parts of the package names. If in doubt please consult a Java book).
<target name="enhance" description="JPOX enhancement">
<taskdef name="jpoxenhancer" classpathref="enhancer.classpath" classname="org.jpox.enhancer.tools.EnhancerTask" />
<jpoxenhancer classpathref="enhancer.classpath"
dir="${jdo.file.dir}"
failonerror="true"
verbose="true">
<jvmarg line="-Dlog4j.configuration=${log4j.config.file}"/>
</jpoxenhancer>
</target> |