Filtering out Javadoc tag warnings
Published March 9, 2007 by John
Javadoc is an amazing tool. It’s hard to imagine dealing with the Java libraries, let alone any other component or project API, without it. One thing that’s annoying, though, is that it is chatty, and it is hard to tell it “do your job, and don’t tell me all of the things you want to warn me about.” When running Javadoc as just one part of a larger project build, a chatty tool makes it harder to spot legitimate build errors in the build log file. There are some switches to quiet Javadoc down a bit, but some things it just seems hard or impossible to turn off, and tag warnings was one, or so I thought.
A project that I’m on right now makes heavy use of XDoclet for generating integration code (EJBs, Struts, JBoss) and that uses Javadoc tags to specify the meta information. The problem for the lowly Javadoc tool, though, is that it doesn’t know anything about these tags, and while it will safely ignore them, it feels that it has to tell you about each and every tag that it is ignoring.
Although it’s nothing very new, I just came across a suggestion to use the <tag> element of the Ant Javadoc task to filter out some of that noise. That’s very slick, however I don’t want to fill up my build script with a whole list of XDoclet tags to ignore.
The great Ant folks thought of this, and the tag element in the javadoc task lets you specify a file that lists all of the tags. Hmm, that’s better, but then how do I get that file? The XDoclet folks don’t seem to provide one, but it turns out that the tags are defined for documentation purposes in nice XML files. Bring on XSLT and a solution starts to emerge.
First we need the XDoclet source. Grab that and unpack it. The tag descriptions, we discover, are in a consistent place: (xdoclet home)/modules/(module name)/src/META-INF/xtags.xml.
Next, we need an XSLT to generate the file that Ant needs. All we want to do is grab the name of the tag and print out a line that tells Javadoc to ignore the tag. Each line will look like this:
ejb.bean:x:ejb.bean
The Javadoc doc describes the format of this line and there are in fact other things you can do besides just ignore the tag, but that’s my goal here.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" indent="yes" />
<xsl:template match="/">
<xsl:apply-templates select="//tags/tag/name"/>
</xsl:template>
<xsl:template match="name">
<xsl:value-of select="."/>:x:<xsl:value-of select="."/><xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
This gives us a way to extract the tags for a single module. You can then run an XSLT engine and point it at each of the module files you want. Since I’m in an Ant mode right now, here’s what it might look like to do this with Ant. I added another step to accumulate the results into a single file that I can choose to use instead of the individual files.
<target name="gen-xdoclet-tagfile"
description="Create files of XDoclet tags for Javadoc filters">
<delete file="${xdoclet.alltags.file}"/>
<gen-xdoc-taglist module="apache"/>
<gen-xdoc-taglist module="ejb"/>
<gen-xdoc-taglist module="hibernate"/>
<gen-xdoc-taglist module="jboss"/>
<gen-xdoc-taglist module="spring"/>
</target>
<macrodef name="gen-xdoc-taglist">
<attribute name="module"/>
<attribute name="extra.file" default="${xdoclet.alltags.file}"/>
<sequential>
<xslt basedir="." destdir="."
in="${xdoclet.home}/modules/@{module}/src/META-INF/xtags.xml"
out="${xdoclet.tagfile.base}/@{module}-tagfilter.txt"
style="xdoclet-tags.xsl"/>
<concat destfile="@{extra.file}" append="true">
<fileset file="@{module}-tagfilter.txt"/>
</concat>
</sequential>
</macrodef>
Finally, we need to tell our original Javadoc task to use these new files.
<property name="javadoc.taglist.files"
value="ejb-taglist.txt,struts-taglist.txt"/>
<javadoc ...>
...
<tag dir="${basedir}" includes="${javadoc.taglist.files}"/>
Happy day. Our build log is cleaned up, and since XDoclet isn’t changing much, we shouldn’t have to do this again for a while.
Filed under Tools
Posts