Now there’s a nice discovery I recently made in the world of JEE development: Datanucleus is a persistence API that does not depend on the underlying persistence mechanism. Meaning you won’t have to change your POJOs if you decide to move from RDBMS to Amazon S3, XML, JSON, MS Excel or any other of the various supported mechanisms. The specifics on the persistence are kept in a configuration file, entities can be annotated via JDO’s @PersistenceCapable. In my view this absolutely rocks. I will prefer it over JPA from now on.
The way it works is that annotated classes are ‘enhanced’, meaning their bytecode is modified to include all the necessary functionality. This can be done at build time: Ant tasks and a Datanucleus Eclipse plugin are part of the package.
There’s a small catch: I happen to develop JEE applications via Eclipse, with hot deployment to an application server and EJB modules split across different projects. After a while I got annoyed by:
- Noticeable delays caused by enhancement: with Eclipse set to ‘build automatically’, each recompilation causes the enhancer plugin to run. This is the case even if the class compiled is not an entity. It takes long enough to be noticed by the impatient.
- Hot deployment failures due to synchronisation issues between enhancer and deployer (Glassfish Eclipse in my case).
- I’d prefer to have a single process for enhancement, instead of having to update my Ant scripts and using the Eclipse plugin as well.
The elegant solution provided by Datanucleus is enhancement at runtime, not build time:
JDOEnhancer enhancer = JDOHelper.getEnhancer();
// add entities to be enhanced to this list...
Properties properties = new Properties();
PersistenceManagerFactory factory =
PersistenceManager persistenceManager =
Important notes: there’s a few catches:
- This only works within a web application, for classes (entities) deployed in WEB-INF/classes. This is because the enhancer will attempt to overwrite the original *.class files with the enhanced *.class files. If your application server explodes the EAR into a directory structure, this will succeed. If the original classes were bundled in a *.jar file, then the enhancement will fail on write. Consequently, ejb-jars or utility jars within the EAR can not be enhanced at runtime.
- Make sure the enhancement process has sufficient file permissions to write into WEB-INF/classes and its content. Sounds obvious if you think of it. Costs hours debugging if you don’t.
Conclusion: There is a way to implement runtime ‘enhancement’ for Datanucleus. No change to the build process is required. It is limited to the web module of a JEE application, but allows to introduce the beauty of JDO/Datanucleus in the most non-invasive way. Hopefully, the enhancement process will be improved to support enhancement on the fly, without the attempt to overwrite *.class files. This would allow to use JEE structures where entities reside within a separate ejb module…