Customize javadoc output with doclets

While you probably know that the javadoc tool is used to generate the standard code documentation, you may be unaware that the javadoc is a pluggable documentation tool.

While you probably know that the javadoc tool is used to generate the standard code documentation, you may be unaware that the javadoc is a pluggable documentation tool.

That means you can create your own class, or doclet, to perform any task, using your source code as an input. To create your own doclet, create a class that implements the following method:

public static boolean start(RootDoc root)

It's unnecessary to implement any interfaces or extend any particular class, although you may choose to extend the predefined class com.sun.javadoc.Doclet.

When you execute the javadoc tool, you inform it that you want your class to process the source documents by using the doclet switch. A typical execution looks like this:

>javadoc -docletpath bin -doclet tips.DocletTip src/tips/*.java

Note that you'll need to include the tools.jar file in your classpath when compiling your doclet class. (You can find tools.jar in your JAVA_HOME/lib directory.)

Your doclet class's start method will be passed an instance of com.sun.javadoc.RootDoc. You can use the RootDoc to access all the classes and all of the classes' methods and fields. For each of these objects, you can interrogate any javadoc objects assigned to them.

Many third parties take advantage of javadoc's plug-in architecture, leveraging this feature by creating their own custom tags. You can do this too.

An easy way to get the values of all your tags for a class is to use the tags() method of com.sun.javadoc.ClassDoc. You can call the tags method either with a String object or with no arguments. If you only want to see your tags, then you would call tags() with the name of your custom tags. Say your custom tag is jndi-name; the call would look like this:

Tag[] tags = classes[i].tags("jndi-name");

If you want to write your own doclet, here is a more complete example to get you started:

package tips;

import com.sun.javadoc.ClassDoc;
import com.sun.javadoc.FieldDoc;
import com.sun.javadoc.MethodDoc;
import com.sun.javadoc.RootDoc;
import com.sun.javadoc.Tag;

/**
 * @jndi-name doclet_tip
 * @unid 1
 */
public class DocletTip {
    public static boolean start(RootDoc root) {
        ClassDoc[] classes = root.classes();

        for (int i = 0; i < classes.length; i++) {
            System.out.println(classes[i]);

            Tag[] tags = classes[i].tags("jndi-name");
            for (int j = 0; j < tags.length; j++) {
                System.out.println("  tag: " + tags[j]);                
            }

            FieldDoc fields[] = classes[i].fields();
            for (int j = 0; j < fields.length; j++) {
                System.out.println("  field: " + fields[j]);
            }
            
            MethodDoc methods[] = classes[i].methods();
            for (int j = 0; j < methods.length; j++) {
                System.out.println("  method: " + methods[j]);
            }            
        }

        return true;
    }
}

David Petersheim is the Director of Application Development with Genscape, Inc. He designs and develops server-side applications to acquire and process real-time energy data.