Building an EJB Module with XDoclet
If you’ve been developing a lot of EJBs (version 1 and 2) you have probably used XDoclet to generate all of the EJB interfaces and deployment descriptors for you. Using XDoclet is easy: by adding Javadoc annotations to your classes, you can run the XDoclet processor to generate those files for you. When writing EJBs it means you simply have to write your EJB implementation class and XDoclet will generate the Home interface, the Remote and Local interfaces, the container-specific deployment descriptors, and the ejb-jar.xml descriptor.
Note: If you’re an EJB3 user, you can safely skip this section – you won’t need it!
Here’s an extract of the TradeBean session EJB using Xdoclet:
/**
* Trade Session EJB manages all Trading services
*
* @ejb.bean
* display-name="TradeEJB"
* name="TradeEJB"
* view-type="remote"
* impl-class-name=
* "org.apache.geronimo.samples.daytrader.ejb.TradeBean"
* @ejb.home
* generate="remote"
* remote-class=
* "org.apache.geronimo.samples.daytrader.ejb.TradeHome"
* @ejb.interface
* generate="remote"
* remote-class=
* "org.apache.geronimo.samples.daytrader.ejb.Trade"
* […]
*/
public class TradeBean implements SessionBean
{
[…]
/**
* Queue the Order identified by orderID to be processed in a
* One Phase commit […]
*
* @ejb.interface-method
* view-type="remote"
* @ejb.transaction
* type="RequiresNew"
*[…]
*/
public void queueOrderOnePhase(Integer orderID)
throws javax.jms.JMSException, Exception
[…]
To demonstrate XDoclet, create a copy of the DayTrader ejb module called ejb-xdoclet. As you can see in Figure 4-7, the project’s directory structure is the same as in Figure 4-6, but you don’t need the ejb-jar.xml file anymore as it’s going to be generated by Xdoclet.

Figure 4-7: Directory structure for the DayTrader ejb module when using Xdoclet
The other difference is that you only need to keep the *Bean.java classes and remove all of the Home, Local and Remote interfaces as they’ll also get generated.
Now you need to tell Maven to run XDoclet on your project. Since XDoclet generates source files, this has to be run before the compilation phase occurs. This is achieved by using the Maven XDoclet plugin and binding it to the generate-sources life cycle phase. Here’s the portion of the pom.xml that configures the plugin:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xdoclet-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>xdoclet</goal>
</goals>
<configuration>
<tasks>
<ejbdoclet verbose="true" force="true" ejbSpec="2.1" destDir=
"${project.build.directory}/generated-sources/xdoclet">
<fileset dir="${project.build.sourceDirectory}">
<include name="**/*Bean.java"></include>
<include name="**/*MDB.java"></include>
</fileset>
<homeinterface/>
<remoteinterface/>
<localhomeinterface/>
<localinterface/>
<deploymentdescriptor
destDir="${project.build.outputDirectory}/META-INF"/>
</ejbdoclet>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
The XDoclet plugin is configured within an execution element. This is required by Maven to bind the xdoclet goal to a phase. The plugin generates sources by default in ${project.build.directory}/generated-sources/xdoclet (you can configure this using the generatedSourcesDirectory configuration element).
It also tells Maven that this directory contains sources that will need to be compiled when the compile phase executes. Finally, in the tasks element you use the ejbdoclet Ant task provided by the XDoclet project (for reference documentation, see this site).
In practice, you can use any XDoclet task (or more generally any Ant task) within the tasks element, but here the need is to use the ejbdoclet task to instrument the EJB class files. In addition, the XDoclet plugin will also trigger Maven to download the XDoclet libraries from Maven’s remote repository and add them to the execution classpath.
Executing mvn install now automatically executes XDoclet and compiles the generated files:
/**
* Trade Session EJB manages all Trading services
*
* @ejb.bean
* display-name="TradeEJB"
* name="TradeEJB"
* view-type="remote"
* impl-class-name=
* "org.apache.geronimo.samples.daytrader.ejb.TradeBean"
* @ejb.home
* generate="remote"
* remote-class=
* "org.apache.geronimo.samples.daytrader.ejb.TradeHome"
* @ejb.interface
* generate="remote"
* remote-class=
* "org.apache.geronimo.samples.daytrader.ejb.Trade"
* […]
*/
public class TradeBean implements SessionBean
{
[…]
/**
* Queue the Order identified by orderID to be processed in a
* One Phase commit […]
*
* @ejb.interface-method
* view-type="remote"
* @ejb.transaction
* type="RequiresNew"
*[…]
*/
public void queueOrderOnePhase(Integer orderID)
throws javax.jms.JMSException, Exception
[…]
You might also want to try XDoclet2. It’s based on a new architecture but the tag syntax is backward-compatible in most cases. There’s also a Maven 2 plugin for XDoclet2 at this site. However, it should be noted that XDoclet2 is a work in progress and is not yet fully mature, nor does it boast all the plugins that XDoclet1 has.

