ONJava.com -- The Independent Source for Enterprise Java
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

Developing with JAXB and Ant, Part 2

by Joseph Shelby
03/13/2002

In the first article in this two-part series, we looked at some advanced uses of Jakarta Ant's build tool to handle automatically executing xjc, the code-from-XML generation tool from the Java API for XML Binding (JAXB). We discovered that Ant has some minor flaws in handling one-to-many file dependencies, and that the only way to guarantee that Ant calls the code generator is to make sure that Ant calls the code generator on every build. In addition, we found that Ant could also be used to solve a smaller (but more common) problem, in which you must explicity provide Javadoc with a list of packages being documented. Both of these problems can be solved, but only by writing our own Ant Task objects to handle them, as we'll see in this article.

The Javadoc Dependency Problem

Let's get used to the Ant API by first attacking the problem of having to provide an explicit list of packages to Javadoc.

Javadoc for Java1 and Java2 specifies two means to list the packages for which documentation is to be generated: as a list on the command line, or as a separate text file, one package per line. Ant adds no conveniences to these methods, unfortunately. The developer has to either keep the build.xml file up to date on the packages in the distribution, or keep an external file up to date. Both have the natural problem of falling out of sync with the actual source tree, so an automated way of setting the package list is obviously useful.

We'd like to see some usage like this (where plistgen is the package list generator):

<target name="javadoc">
<plistgen sourcepathref="src.path.list"
 packagelist="packages.txt"/>
<javadoc sourcepathref="src.path.list"
 packageList="packages.txt" 
 destdir="docs"/>
</target>

or either of the other variations the javadoc task supports -- the sourcepath attribute or sourcepath child elements.

Ant provides two very useful features to help with this. There's a Path object to represent a CLASSPATH that turns out to be useful to represent a sourcepath with multiple entries (as we saw when using the Javadoc task in the first article). Also, because Ant is open source, we can use the excellent example of applying the class in the Javadoc task implementation.

Analyzing the Javadoc task, we see a section of code that's perfect:

private Path sourcePath = null;
public Path createSourcepath() {
  if (sourcePath == null) { 
    sourcePath = new Path(project); 
  }
  return sourcePath.createPath();
}

public void setSourcepath(Path src) {
  if (sourcePath == null) {
    sourcePath = src;
  } else {
    sourcePath.append(src);
  }
}

public void setSourcepathRef(Reference r) {
  createSourcepath().setRefid(r);
}

This supports all three of the desired interfaces to the sourcepath: the reference attribute, the direct attribute, and the child elements. The set methods are for the attributes, and the create method supports the child elements, as described in the Ant user guide documentation.

Finally, we need the package listing file, and choose to support the same syntax as the Javadoc task, an attribute named packageList:

private String packageList = null;
public void setPackageList(String s) {
  packageList = s;
}

Finally, the only method we need to implement is execute(). The build.xml document is enforced in the execute method, since there isn't a specific DTD or schema to validate against, and the code can't know that a parameter hasn't been set until then.

Java and XML

Related Reading

Java and XML
Solutions to Real-World Problems
By Brett McLaughlin

We start execute() with the validation checks, throwing the BuildException to force a build failure on a syntax problem.

public void execute() {
if (packageList == null) throw new 
  BuildException("No packageList specified");
if (sourcePath == null) throw new
  BuildException("No sourcepath specified");

Pages: 1, 2

Next Pagearrow