XDoclet can easily be one of the more versatile cross-technology code-generation tools in your Java programming toolbox. Unfortunately, developers often overlook XDoclet's general utility and use it only when it's bundled as a hidden element of a larger development framework or an IDE. XDoclet is often seen as difficult to apply for custom solutions. This article aims to debunk this myth, stripping XDoclet of its usual trappings of complexity and revealing how you can use this code-generation engine to your advantage.
I'll demonstrate XDoclet's utility with a hands-on example that takes a POJO (plain old Java object) and uses XDoclet to generate all the files that make up a complete Web application for data entry into a relational database. The example explores XDoclet's custom templated code generation, as well as its built-in support for the Hibernate object-relational mapping tool, the Struts Web-application framework, and application server integration (see Resources).
XDoclet's core functionality is to generate code (and/or other configuration/data files) based on a combination of:
- Specially tagged Java source file(s)
- Predefined templates
XDoclet has several unique advantages over other template-based code-generation technology (such as Velocity; see Resources):
- XDoclet is tightly integrated with Apache Ant (see Resources), providing highly automated operations.
- You embed XDoclet tags that control code generation and template processing as in-line comments within the input Java source-code files. This eliminates the need to synchronize multiple related source and control files.
- XDoclet's built-in Java parser uses its intimate understanding of the structure of Java code to create an internal structural model of the input Java code. This structural model is frequently called metadata, because it contains data about the associated code.
- XDoclet's templating logic has complete access to the internal structural model of the input Java code.
Here, I'll take a deeper look into how XDoclet works to help you understand these features.
Figure 1 shows XDoclet's required input and generated output.
Figure 1. The XDoclet black box

You can see that Java source code containing embedded XDoclet tags is the input to the system. Driven by Apache Ant, XDoclet processes the input code and generates output text files that can be Java source, HTML pages, XML documents, and so on. To process the input, XDoclet draws on templates (stored in .xdt files) and tag handlers (coded in Java). XDoclet packages templates and tag handlers into "modules" that address different problem domains.
The structural model that XDoclet builds
XDoclet parses the input Java source code containing embedded XDoclet tags and builds a highly detailed structural model of the code. Each element in the structural model represents a Java construct in the source code. Figure 2 illustrates the structural model, revealing the code constructs and relationships that XDoclet tracks.
Figure 2. XDoclet's internal structural model of parsed Java code

The structural model in Figure 2 tracks code constructs (model elements) such as classes, interfaces, and methods. The model also tracks relationships among the elements, such as inheritance and interface implementation. The XDoclet tags you embed within the source code, as in-line comments, are also parsed and tracked within the model as attributes of the model elements.
Figure 3 shows the internals of XDoclet, revealing the functional pieces that make it work.
Figure 3. Functional blocks inside XDoclet

As Figure 3 shows, Apache Ant controls the configuration and operation of XDoclet at runtime. XDoclet parses incoming Java source code and creates the structural model in memory. The template engine generates the output files by processing a set of templates and tag handlers. The templates and tag handlers can be either built-in or custom. The templates and tag handlers have full access to the structural model during code generation.
A smart code-generation engine that understands the structural model of Java code isn't a new concept. In fact, this is precisely how the Javadoc utility that's included with the JDK operates. By parsing a set of Java source files commented with special Javadoc tags, the Javadoc utility can generate HTML documentation for all of a Java program's structural elements, including classes, interfaces, fields, and methods. The Javadoc utility also has built-in knowledge of special Java language concepts such as inheritance, abstract classes, storage classes, and modifiers.
XDoclet was born from the observation that a generalized version of Javadoc for arbitrary code generation could be extremely useful in many programming situations. However, the actual Javadoc source code isn't designed for generalized code generation, but rather is intimately tied to the generation of HTML documentation. Unable to reuse existing code, the XDoclet development team rewrote the engine from scratch and optimized its performance significantly.
What, then, makes it appear so complex? The answer lies in the fact that XDoclet is almost never discussed in isolation, but always in the company of other complex technology. Figure 4 shows the shrouds of complexity that surround XDoclet (and see the sidebar, Why XDoclet seems more complex than it is).
Figure 4. XDoclet's complex coupling

In Figure 4, you can see that XDoclet is intimately tied to:
- Apache Ant, which controls its operation. XDoclet exists as a set of Ant tasks and cannot execute without Ant.
- The details of the specific problem domains associated with the generated files.
XDoclet by itself is surprisingly straightforward, as the working code in the following example will show.
Now you're ready see XDoclet at work by exploring the data-entry application example I promised you. (To download the Java code, XDoclet templates, and Ant scripts featured in this example, click on the Code icon at the top or bottom of this article or see the Download section.) Start by examining the Java code in Listing 1, which represents a customer's address. It's coded as a JavaBean component, with the XDoclet tags in bold text:
Listing 1. AddressBean.java source file with XDoclet tags markup
package com.ibm.dw.beans;
import java.io.Serializable;
/**
* @dw.genStrutsAction action="/addAddress.do"
* @hibernate.class table="ADDRESS"
*/
public class AddressBean implements Serializable {
private String streetNumber = "";
private String street = "";
private String city = "";
private String country = "";
private String postalCode = "";
private long id = 0;
public AddressBean() {
}
/**
* @dw.genStruts formlabel="Street Number"
* @hibernate.property length="10"
*/
public String getStreetNumber() {
return streetNumber;
}
public void setStreetNumber(String inpStreetNumber) {
streetNumber = inpStreetNumber;
}
/**
* @dw.genStruts formlabel="Street"
* @hibernate.property length="40"
*/
public String getStreet() {
return street;
}
public void setStreet(String inpStreet) {
street = inpStreet;
}
...... more Address bean properties ......
/**
* @hibernate.id generator-class="native"
*/
public long getId( )
{
return id;
}
public void setId(long inId) {
id = inId;
}
}
|
In Listing 1, note that you embed the XDoclet tags within comments immediately before an associated code element (such as a field, method, interface, or class). XDoclet creates an attribute for each tag, attached to the code element in the structural model, when it parses the source. Pay attention to the @dw.genStruts tag for now, because it's one that the first template in this example will use.
For the example, your requirement is to generate the code for a new Java class -- a Struts form bean. Struts will use this bean to hold and transport user input. The bean must contain all the data fields in the form as bean properties, and it must be a subclass of org.apache.struts.action.ActionForm.
To generate the code for the form bean, you create an XDoclet template according to the pseudocode shown in Listing 2. The bold text in braces represents the control-flow logic and the text substitution that you want to take place. Note how the template extracts information from the structural model of the parsed Java source file:
Listing 2. Pseudocode template for generating the AddressBeanForm.java Struts form bean code
package {package name of source class};
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
/**
* Form Bean class for {name of source class};.
*
* @struts.form name="{name of source class}Form"
*/
public class {name of source class}Form extends ActionForm {
{loop through all the methods in the source class}
{if the method is a JavaBean "getter" method}
{if the method has been marked with the @dw.genStruts tag }
private {return type of method}{name of the JavaBean property};
public {return type of method}{name of the getter method for this property}(){
return {name of JavaBean property};
}
public void {name of the setter method for this property}(
{return type of method} value) {
{name of the JavaBean property} = value;
}
{end of if @dw.genStruts}
{end of if JavaBean getter}
{end of loop} |
The code inside the loop in Listing 2 generates a field declaration, a getter method, and a setter method for each getter method tagged with @dw.genStruts in the input source code.
Listing 2 uses an easy-to-understand pseudocode for the template substitution tags. The actual XDoclet template tags are rather verbose. Listing 3 shows the genformbean.xdt template. (All XDoclet templates are stored in .xdt files.) I've highlighted the XDoclet template tags in bold text for easy reference against the pseudocode.
Listing 3. Actual XDoclet template code for generating the Struts form bean Java code
package <XDtPackage:packageName/>;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
/**
* Form Bean class for <XDtClass:className/>.
*
* @struts.form name="<XDtClass:className/>Form"
*/
public class <XDtClass:className/>Form extends ActionForm {
<XDtMethod:forAllMethods>
<XDtMethod:ifIsGetter>
<XDtMethod:ifHasMethodTag tagName="dw.genStruts">
private <XDtMethod:methodType/> <XDtMethod:propertyName/>;
public <XDtMethod:methodType/> <XDtMethod:getterMethod/>(){
return <XDtMethod:propertyName/>;
}
public void <XDtMethod:setterMethod/>(<XDtMethod:methodType/> value) {
<XDtMethod:propertyName/> = value;
}
</XDtMethod:ifHasMethodTag>
</XDtMethod:ifIsGetter>
</XDtMethod:forAllMethods> |
You can find a list of available tags for XDoclet templates by consulting the XDoclet "Template Language" documentation (see Resources).
To run the template against the AddressBean.java source file, use the following Ant command line:
ant -Dbase.class.java=Address genstruts |
This command executes a custom Ant target (see the sidebar, Fluency in Ant scripting) to process the genbeanform.xdt template. The XDoclet-supplied Ant task called xdoclet.DocletTask is used to run a template file. See the build.xml file in the sample code for more information if you are interested in the Ant details.
As XDoclet processes the template, it generates the AddressBeanForm.java file in the subdirectory named generated. Listing 4 shows this file, with all the text substituted during template processing:
Listing 4. XDoclet-generated Java source code containing the Struts form bean
package com.ibm.dw.beans;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.upload.FormFile;
/**
* Form Bean class for AddressBean.
*
* @struts.form name="AddressBeanForm"
*/
public class AddressBeanForm extends ActionForm {
private java.lang.String streetNumber;
public java.lang.String getStreetNumber(){
return streetNumber;
}
public void setStreetNumber(java.lang.String value) {
streetNumber = value;
}
private java.lang.Stringstreet;
public java.lang.String getStreet(){
return street;
}
public void setStreet(java.lang.String value) {
street = value;
}
...... more bean properties .....
}
|
Generating a JSP page for data-form input
You can use the same AddressBean.java source file with the genformjsp.xdt template to generate a data-entry-form JSP page. Listing 5 shows genformjsp.xdt:
Listing 5. XDoclet template for generating a JSP page using the Struts taglib to display an HTML form
<%@ page language="java" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html:html>
<head>
</head>
<body bgcolor="white">
<html:errors/>
<html:form action="<XDtClass:classTagValue tagName='dw.genStrutsAction' paramName='action' /> >"
<table border="0" width="100%">
<XDtMethod:forAllMethods>
<XDtMethod:ifIsGetter>
<XDtMethod:ifHasMethodTag tagName="dw.genStruts" >
<tr>
<th align="right">
<XDtMethod:methodTagValue
tagName="dw.genStruts" paramName="formlabel"/>
</th>
<td align="left">
<html:text property="<XDtMethod:propertyName/>"
size="<XDtMethod:ifHasMethodTag tagName="hibernate.property" >
<XDtMethod:methodTagValue tagName="hibernate.property" paramName="length"/>
</XDtMethod:ifHasMethodTag>"/>
</td>
</tr>
</XDtMethod:ifHasMethodTag>
</XDtMethod:ifIsGetter>
</XDtMethod:forAllMethods>
<tr>
<td align="right">
<html:submit>
Submit
</html:submit>
</td>
<td align="left">
<html:reset>
Reset
</html:reset>
</td>
</tr>
</table>
</html:form>
</body>
</html:html>
|
Note the use of the <XDt:methodTagValue> to obtain an attribute value specified in the XDoclet tags within the original AddressBean.java code.
The genformjsp.xdt template shown in Listing 5 above is also processed when you execute the genstruts Ant target. You can find the generated AddressBeanForm.jsp file in the generated subdirectory and examine it to review the template substitutions.
You can use XDoclet to generate any text-based output. The example I've shown you uses XDoclet to generate Java code, JSP pages, XML files, configuration files, and more. It creates a complete data-entry Web application from a single XDoclet-tagged Java source file, AddressBean.java. In doing so, it exercises the built-in templates (residing in JAR files called modules) in XDoclet for generating:
- Struts configuration and support files
- Hibernate configuration and support files
- A deployment descriptor (web.xml) for the Web application
Table 1 shows all the generated files (often called artifacts) for the sample application:
Table 1. XDoclet-generated artifacts for AddressBean.java
| Generated Artifact | Description | Location |
| AddressBeanForm.java | A Java source file containing a form bean class used in Struts form handling | generated directory |
| AddressBeanForm.jsp | A JSP form using the Struts tag library to accept user input of addresses | jsp directory |
| AddressBeanAction.java | A Struts action class to accept the input value and use Hibernate to store the values in a relational database | generated directory |
| AddressBean.hbm.xml | The Hibernate mapping file to map between the AddressBean Java object and the relational ADDRESS table in the database | web/classes directory |
| dwschema.sql | The schema of the RDBMS table for persisting instances of AddressBean objects | sql directory |
| hibernate.cfg.xml | The configuration file for the Hibernate runtime | web/classes directory |
| web.xml | The deployment descriptor for the generated Web application | web directory |
| struts-config.xml | The configuration file for the Struts framework | web directory |
In this article, you've examined in detail the generation of the first two artifacts listed in Table 1 and explored the templates that generated them. The AdddressBeanAction.java artifact is generated similarly using a template called genaction.xdt. XDoclet comes with built-in templates and tag handlers for generating the other artifacts in Table 1.
Table 2 lists the Ant target and Ant task for each of the generated artifacts. You can execute each of the Ant targets in the table to generate the related artifact. All of the generated artifacts, together with the original AddressBean.java, form the example Web application. You'll also find a default Ant target called all that will do everything for you, including creating a WAR (deployable Web Archive) for the application. Be sure to read the README.txt in the code distribution before proceeding.
Table 2. Ant targets and Ant tasks for the generated artifacts
| Ant target | Ant task | Artifact |
genstruts | xdoclet.DocletTask | AddressBeanForm.java |
genstruts | xdoclet.DocletTask | AddressBeanForm.jsp |
genstruts | xdoclet.DocletTask | AddressBeanAction.java |
generateHIB | xdoclet.modules.hibernate.HibernateDocletTask | AddressBean.hbm.xml |
generateHIB | xdoclet.modules.hibernate.HibernateDocletTask | hibernate.cfg.xml |
createDDL | xdoclet.modules.hibernate.HibernateDocletTask | dwschema.sql |
generateDD | xdoclet.modules.web.WebDocletTask | web.xml |
generateDD | xdoclet.modules.web.WebDocletTask | struts-config.xml |
XDoclet is a useful, intelligent code generator you can use to automate many of your everyday Java development tasks. Don't be put off by its seemingly complex facade. By becoming proficient in XDoclet (and the associated Apache Ant) you can realize valuable time savings that can pay off many times over in your future development work.
| Name | Size | Download method |
|---|---|---|
| j-xdoclet-code.zip | 10KB | HTTP |
Information about download methods
- Learn more about XDoclet at the official open source site, which features the latest source code, downloads, documentation, FAQ, and mailing lists.
- Download the latest version of the Apache Ant build management and automation tool.
- Visit the official Hibernate site for the latest version of the Hibernate persistence layer, documentation, mailing lists, and community news.
- Check out the latest version of the Struts MVC framework.
- For an open source application server you can use with the example in this article, try the Tomcat 5 server.
- Explore an alternate easy-to-use templating language in Sing Li's article "Client and server-side templating with Velocity" (developerWorks, February 2004).
- XDoclet in Action (Independent Pub Group; 2003), by Walls and Richards, is a complete resource for XDoclet code generation.
- Learn about Java 5's new metadata facility in "Annotations in Tiger, Part 1: Add metadata to Java code" and "Annotations in Tiger, Part 2: Custom annotations" (developerWorks, September 2004).
- Find hundreds more Java technology resources on the developerWorks Java technology zone.
- Browse for books on these and other technical topics.

Sing Li is the author of Professional Apache Tomcat 5, Pro JSP, Third Edition, Early Adopter JXTA, Professional Jini, and numerous other books with Wrox Press. He is a regular contributor to technical magazines and an active evangelist of the P2P evolution. Sing is a consultant and freelance writer and can be reached at westmakaha@yahoo.com.




