|
DataNucleus is developed as a plugin-driven framework and one of the components that is pluggable
is the enhancer of classes.
DataNucleus relies on byte-code enhancement of classes to implement the
PersistenceCapable
and
Detachable
interfaces. It provides class enhancer plugins using Apache BCEL and ObjectWeb ASM.
You can extend DataNucleus's capabilities using the plugin extension
org.datanucleus.enhancer.enhancer
.
|
Plugin extension-point
|
Key
|
Description
|
Location
|
|
org.datanucleus.enhancer.enhancer
|
bcel
|
Class Enhancer using Apache BCEL
|
datanucleus-enhancer
|
|
org.datanucleus.enhancer.enhancer
|
asm
|
Class Enhancer using ASM
|
datanucleus-enhancer
|
Any class enhancer plugin will need to implement
org.datanucleus.enhancer.ClassEnhancer
.
So you need to implement the following interface
package org.datanucleus.enhancer;
public interface ClassEnhancer
{
/**
* Check whether the class is enhanced.
* @return Whether the class is already enhanced.
*/
boolean checkEnhanced();
/**
* Method to enhance the class definition internally.
* @return Whether the class was enhanced successfully
*/
boolean enhance();
/**
* Method to save the (current) class definition bytecode into a class file.
* Only has effect if the bytecode has been modified (by enhance()).
* If directoryName is specified it will be written to $directoryName/className.class
* else will overwrite the existing class.
* @param directoryName Name of a directory (or null to overwrite the class)
* @throws IOException If an I/O error occurs in the write.
*/
void save(String directoryName) throws IOException;
/**
* Access the class bytecode.
* @return the class in byte array format
*/
byte[] getBytes();
/**
* Method to verify the enhancement state.
* @throws Exception Thrown if an error occurs while verifying
**/
void verify() throws Exception;
/**
* Accessor for the ClassLoaderResolver in use.
* @return ClassLoader resolver
*/
ClassLoaderResolver getClassLoaderResolver();
/**
* Accessor for the ClassMetaData for the class.
* @return MetaData for the class
*/
ClassMetaData getClassMetaData();
}
Be aware that you can extend
org.datanucleus.enhancer.AbstractClassEnhancer
.
When we have defined our "ClassEnhancer" we just need to make it into a DataNucleus plugin.
To do this you simply add a file
plugin.xml
to your JAR at the root. The file
plugin.xml
should look like this
<?xml version="1.0"?>
<plugin id="mydomain" name="DataNucleus plug-ins" provider-name="My Company">
<extension point="org.datanucleus.enhancer.enhancer">
<class-enhancer name="MyEnhancer" api="jdo" class-name="mydomain.MyClassEnhancer"
test-class="mydomain.SomeClassInTheClasspath"/>
</extension>
</plugin>
The
test-class
should be the name of a class that needs to be in the CLASSPATH
when running your enhancer.
For example, with BCEL we may specify "org.apache.bcel.generic.ClassGen".
The
api
is the API that your enhancer is to be run against. You can specify it for
JDO and JPA by adding two lines above (one for each).
The only thing remaining is to use your new
ClassEnhancer
plugin. You do this by having
your plugin in the CLASSPATH at runtime, and passing the argument
enhancerName
with value
MyEnhancer
(the name you specified in the plugin.xml file) to the DataNucleus Enhancer.
|
|