Thursday, August 21, 2008

Using the Javadoc Tool


A1. Where can I find the Javadoc tool and its documentation?

Javadoc tool - Included in the JavaTM development kits. You can obtain the Javadoc tool by downloading the relevant JDK or SDK -- this is the only way to obtain the Javadoc tool:

Javadoc 5 is included in J2SE Platform Development Kit Standard Edition 5 (JDK 5)
Javadoc 1.4 is included in Java 2 SDK, Standard Edition v 1.4
Javadoc 1.3 is included in Java 2 SDK, Standard Edition v 1.3
Javadoc 1.2 is included in Java 2 SDK, Standard Edition v 1.2
Javadoc 1.1 is included in JDKTM 1.1
The javadoc executable is in the bin directory.
Javadoc Tool Documentation - This documentation is contained in the Java 2 SDK Documentation, which you can browse here or download separately. The "Javadoc Tool Reference Doc" mentioned below is the central reference to the Javadoc tool and is similar to Unix "man pages". It describes how to set up and run the Javadoc tool, with examples, and contains a reference guide to the tags and options.

Javadoc 5: Browse Javadoc 5.0 Tool Docs Download as part of
JDK 5 docs
Shortcut to Javadoc Tool Reference Doc (Solaris)
Shortcut to Javadoc Tool Reference Doc (Windows)
Javadoc 1.4: Browse Javadoc 1.4 Tool Docs Download as part of
Java 2 SDK v1.4 docs
Shortcut to Javadoc Tool Reference Doc (Solaris)
Shortcut to Javadoc Tool Reference Doc (Windows)

Javadoc 1.3: Browse Javadoc 1.3 Tool Docs Download as part of
Java 2 SDK v1.3 docs
Shortcut to Javadoc Tool Reference Doc (Windows)

Javadoc 1.2: Browse Javadoc 1.2 Tool Docs Download as part of
Java 2 SDK v1.2 docs
Shortcut to Javadoc Tool Reference Doc (Solaris)
Shortcut to Javadoc Tool Reference Doc (Win32)

Javadoc 1.1: Javadoc Tool Reference Doc (Solaris)
Javadoc Tool Reference Doc (Windows) (Single web page --
just use "Save As" to download)


Javadoc Tool Home Page has links to all documentation and related information on the Javadoc tool, including proposed Javadoc tags.

A2. How do I write Javadoc doc comments and tags?

To get details on how to write Javadoc tags and documentation comments, this is the best place at Sun to start:
How to Write Doc Comments for Javadoc describes the tag conventions we follow at Java Software.
Example takes you directly to the first example in this document.
If your doc comments comprise an API specification, you might find this document useful:
Requirements for Writing API Specifications - Standard requirements used when writing the Java 2 Platform Specification. It can be useful whether you are writing API specifications in source file documentation comments or in other formats. It covers requirements for packages, classes, interfaces, fields and methods to satisfy testable assertions.

A3. How do I run Javadoc?

There are two ways to run Javadoc -- on classes and on packages. The examples at the end of the Javadoc Tool Reference Doc describes both ways:
Javadoc 1.4 Solaris Examples
Javadoc 1.4 Microsoft Windows Examples
Javadoc 1.1 has some important bugs, so if using that version, it is imperative to read the Javadoc 1.1 Only section of this FAQ. Also, Javadoc uses parts of the Java Compiler (javac) to parse through the source code. It is therefore simplest if you run Javadoc on the .java source files in the same directory hierarchy as they are in when you compile.
Once you've run Javadoc and want to view the generated HTML, the topmost page is named index.html (or packages.html in Javadoc 1.1).


A4. How do I run Javadoc from within a Java application?

Starting with version 1.4.0, Javadoc has a programmatic interface in the form of an execute method. See Programmatic interface to Javadoc. your_method() {
// your code
String[] javadocargs = { "-d", "docs",
"-sourcepath", "/home/user/src",
"java.applet" };
com.sun.tools.javadoc.Main.execute(javadocargs);
// your code
}



For Javadoc 1.2.x and later, you can call main: your_method() {
// your code
String[] javadocargs = { "-d", "docs",
"-sourcepath", "/home/user/src",
"java.applet" };
com.sun.tools.javadoc.Main.main(javadocargs);
// your code
}


The disadvantages of calling main are: (1) It can only be called once per run -- for 1.2.x or 1.3.x, use java.lang.Runtime.exec("javadoc ...") if more than one call is needed, (2) it exits using Systme.exit(), which exits the entire program, and (3) an exit code is not returned.

For Javadoc 1.1.x, drop com (above) and instead use sun.tools.javadoc.Main.main(javadocargs);.


A5. How can I tell which version of Javadoc I'm running?

Javadoc does not actually have a version number contained anywhere in its executable or classes (tools.jar). By convention, we use the same version number for Javadoc as the JDK or SDK is it located in. Therefore, Java 2 SDK v1.2.2 contains Javadoc version 1.2.2.
To find the Javadoc version, simply find the version of the java executable by executing "javadoc -J-version".

Javadoc 1.2.2 gives this result:

C:\> javadoc -J-version
java version "1.2.2"
Classic VM (build JDK-1.2.2-W, green threads, sunwjit)
The letter "W" is the internal build letter.
Javadoc 1.2 gives this result:

C:\> javadoc -J-version
java version "1.2"
Classic VM (build JDK-1.2-V, green threads, sunwjit)
Javadoc 1.1.8 gives something like this result:

C:\> javadoc -J-version
java version "1.1.8"
To get the actual build letter for 1.1, use "-J-fullversion":
C:\> javadoc -J-fullversion
java full version "JDK1.1.8M"
A6. How do I write a shell script or batch file to run Javadoc?

Typing a javadoc command on the command line is burdensome and error-prone, especially if you use many options. You can move part of the command into files in two different ways:
Use the @file option to place the package or source filenames in a separate file.

On Windows, here is a Windows shell script. Save it to disk (in our example we call it run-javadoc.bat), then run it (run-javadoc.bat).

On Solaris, write a shell script to hold the entire command, save it to a file, make the file executable, then run it. For example, here is a Solaris shell script. Save it to disk (in our example we call it run-javadoc), make it executable (chmod a+x run-javadoc), then run it (run-javadoc).
NOTE - On Solaris, it is very important to make sure the backslash continuation character (\) is the last character on any line, not followed by spaces. If it is followed by a space, javadoc will stop execution and display a misleading error message saying "No package, class, or source file found named ." and will implicate the next option on the command line. For example, in the example shell script above, if a space appears at the end of "-d docs \ ", then javadoc will not execute the next option -use. This would be the error message:
% run-javadoc-SOLARIS
javadoc: No package, class, or source file found named .
1 error
run-javadoc-SOLARIS: -use: execute permission denied
A7. I'm planning to upgrade to a newer version of Javadoc and am wondering what kinds of problems I might encounter?

Please read the 1.4 possible incompatibilities and 1.2 possible incompatibilities of What's New in Javadoc.
Javadoc 1.2 and later versions have been through a much more rigorous design and testing program than 1.1, and have proven to be much more reliable and robust. We have also been careful to write each verison Javadoc to be compatible with documentation comments written for previous versions of Javadoc. However, there may be a few cases where old documentation comments may not "work" the same when compiled with earlier versions. Please let us know of any other incompatibilites you run across.

A8. Is there an easy way to print the many pages generated from Javadoc, such as PDF? Sun currently provides the API docs only in HTML, which is not easily printable.
Which route you go depends on whether you (1) have the source files and are willing to re-generate the documentation, or (2) simply want to print the HTML files (perhaps by converting them first to PDF).
The following two doclets require that you have the source files and convert those doc comments to PDF.
PDF Doclet - Someone has written a PDF Doclet that converts doc comments in source files to a PDF document. We have not tried it, so cannot vouch for it. Please let us know your experience with it. As we understand it, the styles are fixed.

MIF Doclet - If you want high quality and have the source code (containing the doc comments), and FrameMaker, and are willing to re-generate the documentation, you can use the MIF Doclet to convert to PDF (or PS) and print directly to a printer with a single command. You have a lot of flexibility to change the styles however you want.


The following programs convert the HTML files to Postscript or PDF.
HTMLDOC. - Probably the simplest way (but not necessarily free) is to use HTMLDOC. A user has written in to say it's a great program for converting the javadoc-html to a nice postscript- or pdf-document. It runs on Windows and Unix, and there is a free demo Windows version which seems to be fully functional except cannot be run from the command line (for batch processing or providing conversions from a webserver).

html2ps - Otherwise, the easiest way to print the documentation that we have found is to convert the documentation to PostScript using html2ps and then print that. (If you know of a good way of printing many HTML pages, please let us know.)

Jan Kärrman has written a freely available program html2ps which batch-converts files to PostScript for easy printing or conversion to PDF. We have used it only on Solaris. It is fast and works great. If you find that it works on Windows, please let us know. The earlier versions use alternate text rather than printing images.

Setup
html2ps converts HTML files to PS for easy printing.
http://www.tdb.uu.se/~jan/html2ps.html
This directory contains the html2ps program, a readme file and a man page.
Running html2ps on HTML files generated from Javadoc 1.2
Since the HTML files are in different directories, you must include the package names on the command line, or concatenate the HTML files together before running html2ps. For the java.applet package, you would cd to the root api docs directory and run:
% html2ps *.html java/applet/*.html java/applet/class-use/*.html index-files/*.html
> apidocs.ps
Running html2ps on HTML files generated from Javadoc 1.1
Since the HTML files are all in one directory, you can run a simple command:
% html2ps *.html > apidocs.ps
However, this causes classes to be printed one right after another, rather than having classes begin at the top of each page.
Notes
Page Order - If the above steps don't give you the pages in the order you want:
At the beginning of each HTML file put an HTML comment:
(not necessary for Javadoc 1.2, since it automatically does this for you).
Concatenate the HTML files together in the order you want them printed.
Run html2ps on the huge concatenated file.
The comment ensures that each new HTML page will begin on a new physical page when printed. Scripts that performs steps 1 and 2 have been written by Francine Le Peintre, Gerard Sookahet and Xavier Outhier, and are available at:
Concatenate files (English version)
Concatenate files (French version)
GIF Images - While html2ps does not handle GIFs, it does the next best thing, by substituting the alternate text for the GIF. Thus, it works great on the Java API generated from javadoc, which contains alternate text for its heading and bullet images.

No Navigation Bar - If you don't want the navigation bar to appear at the top and bottom of each page, use the -nonavbar option when running javadoc.

About html2ps
Author: Jan Kärrman
Dept. of Scientific Computing, Uppsala University, Sweden
e-mail: jan@tdb.uu.se
html2ps is a Perl script that is freely available. It works great and the author Jan is very responsive. html2ps supports a number of options.

A9. Can I incrementally build a document from different runs of Javadoc?

Basically no, but there is a link feature that may provide what you need. First of all, Javadoc generates one and only one document each time you run it. It cannot modify or directly incorporate results from previous runs of Javadoc. However, it can link to results from previous runs. Here are these two cases:
Incremental Build - If you want to run Javadoc on package p1 and separately run Javadoc on package p2, integrating them into a single document with one overview page and one index page, this is not currently possible. We call this incremental build and are considering it for a future release.

Linking Documents - However, anytime you run Javadoc, you can use the -link or -linkoffline options to make it link to pre-existing documents generated from Javadoc. For example, since every class inherits from java.lang.Object, you can link to that class on our website if you'd like. All that is required is that those exisiting documents contain a file named package-list that lists the packages at that location. (Javadoc 1.2 and later versions automatically generate this file, located in the document's root directory, which also holds index.html.) When Javadoc encounters a package not specified on the command line, it will look in the specified package-list files for that package and link to it.

Inheriting Comments from J2SE - Your code can also automatically inherit comments from interfaces and classes in the J2SE. You can do this by unzipping the src.zip file that ships with the SDK (it does not contain all source files, however), and add its path to -sourcepath. When javadoc runs on your code, it will load the doc comments from those source files as needed. For example, if a class in your code implements java.lang.Comparable, the compareTo(Object) method you implement will inherit the doc comment from java.lang.Comparable.
A10. I'm using -link or -linkoffline but some of my external links do not show up. Why is this?

NOTE: See the related FAQ Why do I get the warning "Class or Package not found in @see tag" or "reference not found"?
NOTE: In 1.4.2 we have removed the import limitation described below by allowing links to any fully-qualified class pointed to with the -link option. For the related bug fix, see: 4662658: With -link, all @see/@link tags should create links to excluded classes

First ensure that the arguments to -link or -linkoffline are correct, and check that the package-list file exists at the location you expect it. You can check the latter by viewing it in a browser -- for example, the package list for the Java 2 Platform, Standard Edition, v1.4 API Specification is at: package-list.
If the above does not apply, it is still possible for a link to not appear due to a limitation in Javadoc. For a link to an external referenced class to actually appear, the class must be referenced in a particular way:

In 1.2.x and 1.3.x, it must be referenced explicitly by name in either a declaration or an import statement.
In 1.4.x, the rules have been relaxed slightly -- it must be referenced by a declaration or any kind of import statement (by wildcard, explicitly by name, or automatically for java.lang.*).
Note that it is not sufficient for it to be referenced in the body of a method. The most common workaround is described below.
If you are using Javadoc 1.2.2, if the above does not apply, and if @see and {@link} links are broken, then check with a -link bug in Javadoc 1.2.2.

Workaround - The most innocuous workaround is to import the class explicitly, by name:

import java.io.File; // workaround to enable @see/@link hyperlink
The wildcard import statement import java.io.* works starting with 1.4.0. We strongly recommmend you add a comment similar to the one shown above to the right of the import statement, so the reason for the import statement can be understood, and can be removed if the Javadoc limitation is removed.
This limitation is further described at How a Class Must Be Referenced for a Link to Appear

A11. Is there a way to redirect links between multiple independently-built HTML Javadoc trees after installing them from independent products into arbitrary locations?

Let's state the question a different way. Let's say a user downloads the JDK and its javadoc-generated API documentation (set A). Next, the user downloads and installs a third-party product with its Javadoc-generated API documentation (set B) in a user-defined location. They would like the references from set B to point to set A.
Currently, Javadoc can create links from set B to set A (using "Linking Documents" in the previous question) but they must be specified at Javadoc build time, and can only be either absolute (using http:// or file:/) or relative, but can't use an environment variable that the user sets to redirect the links.

This limitation is inherent in HTML, which does not allow environment variables in links. Some possible solutions or workarounds that we are aware of are:

Use relative links with -link or -linkoffline and require documentation set B to be located relative to set A (On Solaris, these can be non-relative locations provided you use a symlink to perform the redirect.)
Write a script to change the hard-coded links in set B to the required hard-coded links
Replace the hard-coded links with a programmable link (Javascript? Applet tag? Object tag?) that could perform a redirect at runtime. We have not pursued this solution.
Someday when browser source is XML rather than HTML, dynamic redirects may be possible.
A12. How does your implementation of Javadoc work?
Javadoc requires and relies on the java compiler to do its job. The first thing it does is call part of javac to compile the code, keeping the declarations and doc comments but discarding the implementation. It builds a parse tree and then generates the HTML from that.
In fact, javadoc will run on .java source files that are purely stub files with no method bodies. This means you can run Javadoc in the earliest stages of design, while you are writing the API but have not yet implemented it. Stub files are also a possible format for translating doc comments into other natural languages (French, German, Japanese, etc.).

Relying on the compiler ensures that the HTML output corresponds exactly with the actual implementation. For example, the compiler creates default versions of constructors that are not present in the source code. If Javadoc did not use the Java compiler, it would be difficult to handle these special cases.


A13. Can I run javadoc on source files from other languages, such as C, C++ or VisualBasic?
No. Javadoc runs only on Java source code. See the previous question for the explanation. However, other vendors have worked on such documentation tools. They are listed at the bottom of this page.
A14. How can I create custom Javadoc tags?
Javadoc 1.4 solves this problem with the -tag option to create simple tags and the -taglet option for complex tags (tags with more than one argument, or that require special HTML formatting on output).
To do this in earlier versions of Javadoc, it will take some creative programming on your part. You can start by looking at the example at How can I modify the standard doclet.

We have published a list of proposed tags. In this list you will notice a proposed tag @exclude for preventing parts of API from being documented. We have not developed a doclet containing such a tag (although our MIF doclet provides a way of excluding classes). We will publish doclets on this website that we have created or that others have created and want published.

One developer has created a custom tag @inverse to keep tracks of bi-directional links in the Java code generated by a CASE tool. For instance: class Owner {
/**
* my dogs
* @inverse myOwner
*/
Dog[] dogs;
}

class Dog {
/**
* my master
* @inverse dogs
*/
Owner myOwner;
}


The @inverse tag will allow the UML CASE tool to reverse the two fields 'dogs' and 'myOwner' as only one UML association instead of two, which is the default when no information is provided about the coupling between the two fields. (Didier Simoneau)

A15. Where can I find code examples for the Java API?
While we do not include many code examples in the Java API documentation, we do currently provide thousands of examples separately, for virtually all Java 1.1 API -- practically every class, interface, method, field and constructor -- from The Java Class Libraries: An Annotated Reference, by Patrick Chan and Rosanna Lee. While this book is not on-line, its examples are available for download at:
Java 1.2 code examples for java.lang, java.util, java.io, java.net, java.math and java.text
Java 1.1 code examples for java.lang, java.util, java.io, java.net, java.math and java.text
Java 1.1 code examples for java.applet, java.awt and java.beans
We also provide examples in the Java Tutorial, which is a programmer's guide to Java.

The earlier version Java 1.0 examples are also available at Java 1.0 code examples for java.applet, java.lang, java.util, java.io, java.net and java.awt


A16. How can I exclude or skip certain public members or classes from being documented?
Occasionally you might need to make a class or method public so that it can be accessible from other packages, not because you want it to be part of the public API. Having these methods appear in the documentation merely confuses application developers.
There is currently no Javadoc option to hide, exclude or suppress public members from the javadoc-generated documentation.

Several options are available:

Excluding source files - You can pass into javadoc only the source filenames for all classes you want to document, and exclude those you want to omit. Notice this has the granularity of files, not classes. Therefore, if you exclude a source file that contains nested classes, they would also be excluded. (You can put the list of classes in a command line argument file rather than directly on the command line.) The default Javadoc offers no way to omit classes when passing in package names on the command line.
Excluding individual classes - You can use the Exclude Doclet. This has finer granularity (class rather than source file) than the previous option, and would be more natural to use because you explicitly list in a file the files you want to exclude.
Excluding classes, methods and fields - The yDoc Doclet has this capability, where you mark items with an exclusion tag in the source code. In addition, anyone is welcome to extend the Exclude Doclet above for methods and fields -- we'd be happy to publish it and add your name to the credits.
We are considering @exclude as a proposed tag for excluding members.


A17. How would I create a makefile for documenting arbitrarily large libraries?
One of our developers, John Visosky, has donated a generic batch file and makefile for running javadoc on Windows. Please see Running Javadoc for Large Java Libraries.
A18. May I see the slides presented at the JavaOne Javadoc Birds-of-a-Feather session?
Once at the first page, click on the Java coffee cup logo to go forward to the next slide, click at the top of the left-hand purple vertical stripe to go backward, and click in between those two spots to start over.
A19. How do I generate documentation for packages that contain a package.html file but no java files?
Technically, that's currently not possible -- however, there is a practical workaround, where you include a package-private "placeholder" class in that package. So long as you don't use either the -private or -package option, the class will never appear in your documentation. /**
* Exists only to enable package.html to be included in javadoc
*/
class Placeholder {
}


This is being tracked by Bug 4492654 We hope to remove this restriction.

0 comments: