XDoclet Dynamic Inheritance and Java 5 Generics Support

In this page you will learn how to add support for xdoclet dynamic inheritance (Section 1) and for xdoclet compatibility with java 5 generics sintax (Section 2).

XDoclet Dynamic Inheritance

XDoclet has added support to generate a separate hbm file for a class thus allowing to extend one of our modules class even on the persistence layer.

Say, for example, you want to extend net.smartlab.web.registry.Person class to have foo.bar.Employee which represents a Person plus some specific details (the employment position for example) you wish to persist on the database.

package foo.bar;
 
import net.smartlab.web.registry.Person;
 
/**
 * @hibernate.joined-subclass table="employee"
 * @hibernate.joined-subclass-key column="id"
 */
public class Employee extends Person {
 
    private Position position;
 
    /**
     * @hibernate.many-to-one column="`position`"
     */
    public Position getPosition() { return position; }
 
    public void setPosition(Position position) { this.position = position; }
}

You can simply inherit Person from Employee, but you cannot add the Employee hibernate mapping into the net/smartlab/web/registry/Entry.hbm.xml (where Person mapping is defined) because it's packaged into the smartweb-registry archive. To perform the task you have to define the Employee mapping inside an Employee.hbm.xml in a way similar to the following

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
 
<hibernate-mapping>
 
  <joined-subclass name="foo.bar.Employee" table="employee" extends="net.smartlab.web.registry.Person">
    <key column="id" />
    <many-to-one name="position" class="foo.bar.Position" column="id" foreign-key="position"></many-to-one>
  </joined-subclass>
 
</hibernate-mapping>

Unfortunately to perform this activity with XDoclet generated HBMs you need a feature (@hibernate.mapping) available only with XDoclet version 1.3.0 which has not been released yet! To have XDoclet 1.3 available through maven you need to:

  1. checkout xdoclet from its own cvs repository (on sourceforge)
  2. build the core library and all the modules
  3. install the xdoclet:xdoclet-1.3-SNAPSHOT and relative modules into your Maven repository
  4. install a slightly modified version of the org.codehaus.mojo:xdoclet-maven-plugin (with an updated pom with updated dependencies to xdoclet and relative modules) into your Maven repository
  5. fix the javadoc tags of your Employee class
  6. tell maven to use your modified version of the org.codehaus.mojo:xdoclet-maven-plugin

I'll not cover downloading xdoclet source or build process, nor I'll tell you how to install artifacts into your Maven repository, but perhaps you could find useful how to modify the xdoclet-maven-plugin. What I've done is simply "home release" a beta-1 version of this plugin with the following steps:

  1. copy from .m2/org/codehaus/mojo/xdoclet-maven-plugin/1.0-alpha-2 (the actually available plugin for xdoclet) the jar and pom files into a folder named .m2/org/codehaus/mojo/xdoclet-maven-plugin/1.0-beta-1-SNAPSHOT
  2. rename xdoclet-maven-plugin-1.0-alpha-2.jar to xdoclet-maven-plugin-1.0-beta-1-SNAPSHOT.jar and xdoclet-maven-plugin-1.0-alpha-2.pom to xdoclet-maven-plugin-1.0-beta-1-SNAPSHOT.pom
  3. edit xdoclet-maven-plugin-1.0-beta-1-SNAPSHOT.pom replacing each occurrence of the string 1.2.3 with 1.3-SNAPSHOT

Now you have your home made, personal and updated org.codehaus.mojo:xdoclet-maven-plugin!

Now you can alter the Employee class instructing XDoclet to produce a separate HBM:

import net.smartlab.web.registry.Person;
 
/**
 * @hibernate.joined-subclass table="employee" extends="net.smartlab.web.registry.Person"
 * @hibernate.joined-subclass-key column="id"
 * @hibernate.mapping
 */
public class Employee extends Person {

As you can see two things have varied from before:

  1. the extends attribute was added and is used by Hibernate mapping to link this HBM to the HBM available within SmartWeb Registry
  2. the hibernate.mapping directive was added to instruct XDoclet to generate a separate HBM

Now you need only to alter your pom.xml and tell Maven to use your custom xdoclet-maven-plugin:

<build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>xdoclet-maven-plugin</artifactId>
        <version>1.0-beta-1-SNAPSHOT</version>
    ....
      </plugin>

For simplicity, if you have a business wide repository I suggest you to share within your colleagues the artifacts you installed on your own Maven repository to avoid the same process to be performed on each separate machine.

XDoclet with Java 5 generics sintax

If you ever tried to generate hibernatedoclet for classes that use generics you would have find out that the parser used by xdoclet is unable to parse the source code generating the following error:

Encountered "<" at line 132, column 17.

Where "<" is exactly the char used to define generics in your code:

ArrayList<Person> friends = new ArrayList<Person>();

The problem is the parser used by xdoclet ,xjavadoc, so changing it can allow you to use generics.

Unfortunately the last official release of xjavadoc is 1.1 and it doesn't include support for generics so you need to do your home made release.

The steps to follow are always the same:

  1. checkout xjavadoc from its own cvs repository (on sourceforge)
  2. build it
  3. install the xdoclet:xjavadoc-1.5-SNAPSHOT into your Maven repository

Now you just need to use this new library in you xdoclet-maven-plugin. As described in the previous section you need to change the pom of the xdoclet-maven-plugin or to create a new version of xdoclet-maven-plugin. It's up to you.

Change the version of xjavadoc to reflect your new library: xjavadoc-1.5-SNAPSHOT

<dependency>
    <groupId>xdoclet</groupId>
    <artifactId>xjavadoc</artifactId>
    <version>1.5-SNAPSHOT</version>
    <scope>runtime</scope>
</dependency>

That's it, now you can use generics in your source code.

Downloadable files

Attached to this page you can find:

  • a package xdoclet-1.3-SNAPSHOT.zip containing the source code and a build from trunk of the core libraries and all the modules;
  • a package xjavadoc-1.5-SNAPSHOT.zip containing the source code and a build from trunk of the custom Java source code parser (for generics support);
  • a package xdoclet-maven-plugin-1.0-beta-1-SNAPSHOT.zip containing two revisions of the currently available 1.0-alpha-2 release of the maven plugin slightly modified to support xdoclet-1.3-SNAPSHOT and generics;

Attachments

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-Share Alike 2.5 License.