JDO Meets Maven

By Andy Jefferson

Background - Maven

Maven is a tool for managing and building projects providing an alternative to the accepted Ant build process. Maven is almost totally plugin-driven, and provides plugins for many common tasks (for example: building EJB components such as WARs and EARs, generating documentation, running unit tests) and related software (for example: Checkstyle, PMD, Clover, JCoverage).

Maven builds on top of the definition of a project. It formalises project definitions such as dependencies (and hence classpaths), versions, source repositories, mailing lists, etc. This project definition provides placeholders for all of the typical metrics important to a project. It formalises the location of the source tree for a project and of the unit tests. This rigorous structure allows Maven's plugins to provide generalised functionality such as building the source tree, running the unit tests, generating javadoc, code analysis, etc.

Maven operates using the concept of goals. Each goal can have "pre" and "post" goals. This structure allows for chaining of operations, with one operation firing off another, and another to achieve some overall end result.

Integrating JDO with Maven

In developing a JDO system, the developer has many concerns - not least the likes of object-relationship mapping - and should, as far as possible, be spared the "administrative" burdens associated with building the system. Maven's formalization of the source tree structure and chaining of actions helps achieve this objective by saving the developer from having to explicitly define tasks like JDO class bytecode-enhancement. Thus, rather than explicitly invoking a bytecode-enhancement task in the system build, Maven is able to provide this activity by way of a plugin, which could even be automatically chained off the existing Java compilation task.

Anatomy of a Maven JDO plugin

A Maven plugin can use a variety of languages, however most commonly utilises Jelly scripting language, at least for definition of the plugin's goals. A Maven plugin typically requires a minimum of 3 files ...

  • project.xml (defining the dependencies of the plugin on other software)
  • plugin.jelly (providing the goals definition)
  • plugin.properties (properties available for configuration)

Maven plugins can use a variety of other scripting and templating utilities, however these are not currently required for the JDO plugins implemented.

Plugins have now been developed for JPOX, and TJDO, though can readily be developed for any JDO implementation. The best way of understanding the process involved is by analysing a Maven JDO plugin - in this case, the JPOX plugin. Here the plugin.jelly file is as follows:

<goal name="jpox"
    description="Enhance classes for use with Java Persistent Objects (JPOX)"
    prereqs="jpox:enhance"/>

<goal name="jpox:init">
    ... snip ... code to generate jpoxClasspath and jpoxMetaDataFiles
</goal>

<goal name="jpox:enhance"
    description="Perform the enhancement of classes for use with JPOX"
    prereqs="jpox:init">
    <echo>JDO-enhancing classes for Java Persistent Objects</echo>

    <ant:java dir="${maven.build.dest}"
        classname="org.jpox.enhance.SunReferenceEnhancer"
        failonerror="true"
        fork="true">
        <classpath refid="jpoxClasspath"/>
        <arg line="${jpoxMetaDataFiles}"/>
    </ant:java>

    <echo>Classes are now JDO-enhanced for Java Persistent Objects</echo>
</goal>

It can be seen that the plugin has several goals, the default one being to run the enhance goal. Since this goal requires (as a prerequisite) the running of the init goal, they are chained.

Some JDO implementations (for example JPOX, or Kodo) allow the generation of the JDO database schema prior to running the JDO-enabled application. This is catered for with additional goal(s). For JPOX again, this is handled as follows

<goal name="jpox:schema-create"
    prereqs="jpox:init">
    <echo>Creating tables for Persistence Capability</echo>

    <ant:java dir="${maven.build.dest}"
        classname="org.jpox.SchemaTool"
        failonerror="true"
        fork="true">
        <classpath refid="jpoxClasspath"/>
        <sysproperty key="database.driver" value="${maven.jpox.database.driver}"/>
        <sysproperty key="database.url" value="${maven.jpox.database.url}"/>
        <sysproperty key="database.user" value="${maven.jpox.database.user}"/>
        <sysproperty key="database.password" value="${maven.jpox.database.password}"/>
        <arg line="-create"/>
        <arg line="${jpoxMetaDataFiles}"/>
    </ant:java>
</goal>

<goal name="jpox:schema-delete"
    prereqs="jpox:init">
    <echo>Deleting tables for Persistence Capability</echo>

    <ant:java dir="${maven.build.dest}"
        classname="org.jpox.SchemaTool"
        failonerror="true"
        fork="true">
        <classpath refid="jpoxClasspath"/>
        <sysproperty key="database.driver" value="${maven.jpox.database.driver}"/>
        <sysproperty key="database.url" value="${maven.jpox.database.url}"/>
        <sysproperty key="database.user" value="${maven.jpox.database.user}"/>
        <sysproperty key="database.password" value="${maven.jpox.database.password}"/>
        <arg line="-delete"/>
        <arg line="${jpoxMetaDataFiles}"/>
    </ant:java>
    </goal>

Hence there are 2 additional goals, one for creating all tables required by JPOX, and a second for deleting these tables. Clearly this has more relevance to schema generation than for existing schemas

Where a JDO implementation allows a particular configuration operation, a Maven plugin goal can be added to deliver this functionality to the Maven user. As a result, individual implementations can add as many goals as they wish to fulfil their users requirements.

Using a Maven JDO plugin

Using the JPOX Maven plugin as an example, the basic enhancement process could be invoked as follows:

maven jpox:enhance

The problem with this is that it burdens the developer with having to explicitly invoke the enhancement process. As an alternative it is possible to integrate bytecode enhancement as an automatic step chained off the basic Java compilation process. This is achieved by including the following in the project maven.xml file:

<postGoal name="java:compile">
    <attainGoal name="jpox:enhance"/>
</postGoal>

So wherever the java:compile goal is called, as a postGoal it runs the jpox:enhance goal, leaving the developer with JDO enabled classes ready to run.

Maven's plugins can be made configurable using properties specified in the plugin.properties file. For the JPOX plugin, the following properties can be set

  • maven.jpox.jdo.fileset.dir : Directory containing the JDO MetaData files
  • maven.jpox.jdo.fileset.include : Fileset include path for JDO MetaData files (default: **/*.jdo)
  • maven.jpox.jdo.fileset.exclude : Fileset exclude path for JDO MetaData files
  • maven.jpox.database.driver : Driver for use in connecting to datastore
  • maven.jpox.database.url : URL defining the datastore
  • maven.jpox.database.user : Login name for the datastore
  • maven.jpox.database.password : Password for the datastore

For example, the following properties could be included in the Maven project.properties file

maven.jpox.jdo.fileset.dir=${basedir}/jdo
maven.jpox.jdo.fileset.include=**/*.jdo
maven.jpox.database.driver=com.mysql.jdbc.Driver
maven.jpox.database.url=jdbc:mysql://localhost/jpox
maven.jpox.database.user={my_username}
maven.jpox.database.password={my_password}

This would define the JDO MetaData files residing under the "jdo" project directory, with names matching *.jdo and would be used when all JDO plugin goals (such as enhance) are called. The 4 database properties are used in the schema-create/schema-delete goals (as seen in the plugin.jelly file earlier).

Invocation of the JPOX schema-create optional goal could be achieved as follows:

maven jpox:schema-create

Conclusion

This article has attempted to give a feel for both the operation of Maven, and how to integrate JDO into a Maven project. The various Maven JDO plugins can be downloaded as follows

About the author

Andy Jefferson is an independent software consultant who has been working in the IT industry for more than 15 years, primarily in the United Kingdom. He is an active participator in several OpenSource projects, primarily JPOX, and Apache JDO, and a member of the JSR243 (JDO2) Expert Group.