Thursday, August 21, 2008

Troubleshooting: Bugs, Errors and Warnings

B1. What bugs are in Javadoc?

There are several places to look for reports of Javadoc bugs and feature requests:
Bug Database - You can list all reports for Javadoc bugs and features by constraining your search to the java category, javadoc subcategory.

Go to: java.sun.com search page

Use the mouse to check the checkbox for "Bugs" (Java Bug Database), uncheck the others, and type terms into the field using the plus sign (+) to require the following word be included and the minus sign (-) to require the word be excluded.
+enhancement to find enhancements only.
-enhancement to find bugs only.
Omit enhancement to find both bugs and enhancements.
Examples:

To find all open javadoc tool bugs and enhancement requests:

+category:java +subcategory:javadoc +state:open
To find all open javadoc tool bugs (not including enhancement requests):
+category:java +subcategory:javadoc +state:open -enhancement
To find all open javadoc tool enhancement requests:
+category:java +subcategory:javadoc +state:open +enhancement
To find all bugs and enhancements (open and closed) for javadoc tool containing the words "interface" and "constants":
+category:java +subcategory:javadoc +interface +constants
Bug Database is also known as "Bug Parade." It is part of Sun Developer Network, which anyone can join for free: Join Sun Developer Network.

This FAQ - For Javadoc 1.1 and 1.2, the most commonly encountered bugs are listed in this FAQ, along with workarounds where possible.

Release Notes - Some major known bugs for 1.4 are listed in its 1.4 Release Notes. (Nothing about Javadoc bugs is mentioned in the 1.2 or 1.3 Release Notes.)

What's New in Javadoc - Each release of the Java 2 SDK includes a list of changes to the Javadoc tool, which lists some of the important bugs fixed in that particular release; see What's New in Javadoc 1.4, 1.3, 1.2.2 and 1.2.

B2. How do I submit bugs and feature requests?

When submitting a bug, be prepared to describe the steps and supply the source files needed to reproduce the bug (or do the best you can). We welcome your bug reports. If you have trouble with this bug submission process, please email us directly.
Go to Report a Bug or Feature Request. Scroll to the bottom, check the checkbox and click "Start a New Report".

Scroll down to "Start a Report". In the "Product/Category" pop-up, choose:
Java 2 Platform Standard Edition, JRE/SDK (J2SE 1.4.x, 5.0)

In the "Subcategory" pop-up menu, choose:
Java API Documentation Generator Tool (javadoc)
This subcategory is for bugs and features in any part of Javadoc tool -- the javadoc tool front end, standard doclet, Doclet API, Taglet API, or doclet toolkit in the JDK. For other doclets, see "Custom Doclet Bugs" below.
NOTE - When choose an operating system, don't choose "Generic/Other", as it won't let you submit a bug (oddly).


Custom Doclet Bugs - You can also submit bugs against custom doclets such as the MIF Doclet, DocCheck Doclet, Localization Doclet, Exclude Doclet (any bug the standard doclet). In step 2 above, these have their own category under "Other Technologies" named "Custom Doclets for the Javadoc Tool"
B3. How do I redirect error messages to a file?
In Windows NT/2000/XP and in Bourne (sh) and Korn (ksh) shells, you can redirect the standard message stream by using the ">" operator, and redirect the error messages stream by using the "2>" operator. For example, to redirect the standard messages to log.std and the error messages to log.err:
C:> javadoc -d docs java.lang >log.std 2>log.err
You may find it much more useful to redirect both streams to the same file, then search through the log file for the string "warning" or "error". (This is easier for Javadoc 1.3 and earlier, because the filename being processed appears in the standard output rather than the error output. However, starting with 1.4, the filename now appears on the same line as the error message.) For example:
C:> javadoc -d docs java.lang >javadoc.log 2>&1
You can redirect standard and error messages in C shell (csh) and T shell (tcsh) by using ">&", such as:
C:> javadoc -d docs java.lang >&javadoc.log
The MS-DOS shell in Windows 95/98/ME does not allow redirection of steams. You must use a shell that does, such as Cygwin or MKS.

B4. I just can't get Javadoc to work on my entire source code; what do you suggest?
Here are some ideas. Basically, start small and work up:
Unset your classpath (Solaris, Windows). If you're using Javadoc 1.1, make sure your API does not contain underscore or other characters outside of A-Z, a-z, 0-9 and period (.).
Try running javadoc on a single source file just to see if your setup is correct. For class MyClass in mypackage, it should generate a class file named "mypackage.MyClass.html" (for 1.1) or "mypackage\MyClass.html" (for 1.2) containing documentation for the class, plus a class hierarchy "tree.html" containing that one class, and an index "AllNames.html" (for 1.1) or "index-all.html" (for 1.2, without -splitindex) or "index-1.html" (for 1.2 with -splitindex) containing the members of that class. In Javadoc 1.1, the links to bullet and heading images will all be broken links unless you copy the images directory to where your HTML files are located (as described elsewhere in this FAQ).
Then try running javadoc on a single package, which will also generate a package file "Package-mypackage.html" (for 1.1) or "package-summary.html" (for 1.2). Source files should be in directories with the same names as the packages. Thus, the file MyClass.java should be in a directory called "mypackage".
If that succeeds, then try it on multiple packages.

B5. I run out of memory -- how much is needed, exactly how do you at Java Software call Javadoc, and how long does it take?

Javadoc does take a lot of memory because (unlike javac) it must simultaneously load all the classes being documented, plus any that are referenced (such as superclasses and superinterfaces). Javadoc 1.1.x uses 40 MB of memory to generate the JDK 1.1.x documentation (22 packages). Javadoc 1.2 requires 120 MB of memory to generate the JDK 1.2 documentation (55 packages), which takes 8 minutes on an Ultra Enterprise with 512 MB of memory. Generating docs for all our public classes including sun.* (129 packages) requires 200 MB and takes 15 minutes on that same machine.
The javadoc 1.1.x command is shown with the -J-mx40m option below. Also, there is a bug in JDK 1.1.2 (fixed in 1.2), where the "ms" value must be smaller than (not equal to) the "mx" value. Without showing the complexity of environment variables and paths, the following is effectively the command that we run on the JDK 1.1 source code: javadoc -J-ms39m -J-mx40m \
-classpath /usr/latest/build/solaris/classes \
-d /usr/latest/build/doc/api \
-sourcepath /usr/latest/src/share/classes:/tmp/javadoc \
java.io java.lang java.lang.reflect java.util java.util.zip \
java.awt java.awt.datatransfer java.awt.event \
java.awt.image java.net java.applet \
java.sql java.rmi java.rmi.registry java.rmi.server \
java.security java.security.acl sun.tools.debug \
java.text java.math java.beans \
java.rmi.dgc java.security.interfaces


Fortunately, there are easier ways to run Javadoc without using the -classpath and -sourcepath options. See the Javadoc reference page.

For javadoc 1.2, this is the command we run (in a Solaris 'make' file) on the JDK 1.2 source code:
javadoc -J-Xms120m -J-Xmx120m \
-splitIndex \
-title $(JAVADOCTITLE) \
-header $(JAVADOCHEADER) \
-footer $(JAVADOCHEADER) \
-bottom $(JAVADOCBOTTOM) \
-d docs/api \
-sourcepath ../src/share/classes/ \
$(COREPKGS)

JAVADOCTITLE = 'JavaTM Platform 1.2 Beta 4 API Specification'

JAVADOCHEADER = 'Java Platform 1.2
Beta 4'

JAVADOCBOTTOM = 'Java is a trademark of Sun Microsystems, Inc.'

COREPKGS = java.applet \
java.awt \
java.awt.color \
java.awt.datatransfer \
java.awt.dnd \
java.awt.event \
java.awt.font \
java.awt.geom \
etc.


For an example using a make file, please see the makefile question.

B6. Why aren't the memory flags (-J-m) recognized in Windows?

In JDK 1.1.x, 1.2 Beta 1 and 1.2 Beta 2 on Microsoft Windows, there is a bug in the Javadoc wrapper that prevents the -J flags from being passed on to the virtual machine. The symptom is that when you specify the -J option, it says "invalid flag", as follows: C:\> javadoc -J-mx40m MyClass.java
javadoc: invalid flag: -J-mx40m
usage: javadoc flags* [class | package]*
-sourcepath Colon-separated list of source-file directories
-classpath Synonym for -sourcepath
...


Workaround - Switch to Javadoc 1.2 Beta3 or later (you can use the -1.1 switch to make it look like the 1.1 javadoc output with gray background and GIF images for headers). Otherwise, bypass the wrapper script in JDK 1.1.x by running the Main class (which contains a "main" method) in the sun.tools.javadoc package, assuming the destination directory is "C:\html":
C:\> java -mx40m sun.tools.javadoc.Main -d html MyClass.java

B7. When I run javadoc on my source package, some of the links are not generated.

For example, for methods that have parameters of type Object, those parameters have no link to documentation for the Object class.

In Javadoc 1.2 and later, use the -link or -linkoffline options to create links to external referenced classes. These are classes outside of the packages passed in to the javadoc command. Therefore, if you run javadoc only on your own, it will not provide links to java.lang.Object unless you include one of these two options.

Javadoc 1.1 does not have these options to generate links to external referenced classes. (Javadoc 1.0 does include links to classes outside of the packages being operated on, but that means those links would be potentially broken links.)

See the next question for a related bug.

Workaround - Use the -link or -linkoffline options, or include the package or class in the javadoc command that you run.


B8. In Javadoc 1.2.2, when using @see or {@link} tags to external API, any links to methods, fields and constructors are missing.


I am calling javadoc with "-link http://java.sun.com/products/jdk/1.2/docs/api". If I link to a class in 1.2.2 it works, but not if I link to a member. With v1.3 both classes and members work! For example: import javax.swing.tree.TreeModel;

/**
* This is an example with a link to the method
* {@link TreeModel#getChildCount(Object) getChildCount()}
* and it doesn't work with JDK 1.2.2
*/



This is a known bug only in 1.2.2. In 1.2.2, the -link and -linkoffline options link only to packages, classes and interfaces but not to members. This bug is not present in either earlier (1.2.0) or later (1.3.0) versions.

Workaround - Use Javadoc 1.2.0 or 1.3.0 (also known as versions 1.2 and 1.3). These are the versions found in the Java 2 SDK versions 1.2.0 and 1.3.0, respectively.

B9. Why do I get the warning "Class or Package not found in @see/@link tag" or "reference not found"?
NOTE: See the related FAQ I'm using -link or -linkoffline but some of my external links do not show up. Why is this?"
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

When @see or {@link} refers to a Java name that is not referenced -- that is, not used anywhere in the implementation of the classes being documented -- javadoc cannot find it, and displays one of these warnings:
javadoc: warning - Class or Package not found, in @see tag: xxx
warning - Tag @see: reference not found: java.util.List
warning - Tag @link: reference not found: java.util.List
The following source file Test.java generates a warning because JSplitPane is not referenced in either the declaration or in an import statement. /**
* @see JSplitPane
*/
public class Test {
}


When you run javadoc, you get a warning:
% javadoc Test.java
javadoc: warning - Class or Package not found, in @see tag: JSplitPane
The follow generates the @see link properly, without warning. Only one of the import statements is needed, depending on the version of Javadoc you are using. The wildcard import javax.swing.* statement is sufficient in 1.4.x. The explicit import javax.swing.JSplitPane statement is required in 1.2.x and 1.3.x. import javax.swing.*; // 1.4 workaround to enable @see link
import javax.swing.JSplitPane; // 1.2 and 1.3 workaround to enable @see link

/**
* @see JSplitPane
*/
public class Test {
}



Workaround - Include a reference to the Java name you want to include, such as importing the class explicitly.

B10. The class comments are missing from the generated docs, but are in the source code. I only get the doc comments for the methods, fields and constructors.

If the class-level doc comments are missing, a common mistake is putting the import statement between the doc comment and the class definition in the source file. There must not be any statements between the class doc comment and the class declaration. /**
* This is the class comment for the class Whatever.
*/

import com.sun; // MISTAKE - Important not to put statements here

public class Whatever {
}


SOLUTION - Move the import statement ahead of the class comment.
B11. When I run javadoc, I get the following exception warning: "Method X declares that it throws class Y, but there is no corresponding @exception item." What does this message mean?
This warning message means that there is no description on the line that contains the @exception tag. The @exception line should look something like:
* @exception ReceiverException An exception thrown by the receiver.
You get the warning if there is a return immediately after the exception name (ReceiverException). If you put the description on the next line, for example, you get this warning.
Workaround - Insert a space after the exception name.

B12. I copied all of my .java files from their package hierarchy into a single directory so it would be easier to run javadoc on them, but it doesn't work. I get the message "Couldn't find "?
If your classes do not all belong to the unnamed package, you must put them in directories named after the packages. Do not put all .java files into the same directory (even if they will compile that way). For example, files belonging to java.awt and java.awt.swing must be in these directories: DIRECTORIES

java
|
|
awt
|
+----------+
| |
swing *.java (java.awt source files)
|
+----------+
|
*.java (java.awt.swing source files)


It is normally not possible for javadoc to run successfully when classes from different packages are in the same directory, because of certain dependencies between classes. Also, it's worthy to note that because javadoc calls parts of the java compiler to parse through the source code, it will not run on source code that is not compilable.
B13. I am documenting 33 packages and added a new package to my javadoc command but this created a "No source files" error.
There is a limit to the number of characters Windows allows on the command line, about 1000 characters. A hint is that the error message lists a package name that is truncated. If the last package name is "com.mypackage", the error message might look like:
Warning: No source files for package com.mypackaC:\project\src
Notice the end of the line is corrupted: com.mypackaC:\project\src. This same problem can occur in Javadoc 1.1 or 1.2.
Workaround - In 1.2 or later you can use the command line argument file feature which allows arguments of any length to be placed in a file:

javadoc @args
This is not implemented prior to 1.2 Beta4, so if using Javadoc 1.1, you must switch to Javadoc 1.2 or later, or run Javadoc on Solaris which has no such length limit (allows at least 10,000 characters).
B14. I get the error "Class xxx already defined".
Problem #1 - This command:
javadoc ca.mcgill.sable.sablecc ca.mcgill.sable.sablecc.lexer

produced this error message: Loading source files for package ca.mcgill.sable.sablecc...
Loading source files for package ca.mcgill.sable.sablecc.lexer...
.\ca\mcgill\sable\sablecc\lexer\Lexer.java:17:
Class ca.mcgill.sable.sablecc.lexer.Lexer already defined
in ca/mcgill/sable/sablecc/lexer/Lexer.java.
public final class Lexer
^
.\ca\mcgill\sable\sablecc\lexer\LexerException.java:10:
Class ca.mcgill.sable.sablecc.lexer.LexerException already defined
in ca/mcgill/sable/sablecc/lexer/LexerException.java.
public class LexerException extends Exception
^
2 errors


When running Javadoc on each package separately, it works ok. When combining them, Javadoc complains about every class in the second package. Am I doing something wrong, or can javadoc just not handle more than one package?

Solution #1 -

Your CLASSPATH includes both the jar file for the classes being documented and the un-jarred source files, so Javadoc thought there were duplicate definitions, but, oddly, only when you run Javadoc with more than one package name. The solution is to remove the jar file from the CLASSPATH. Note that you should be using SOURCEPATH to specify the path to the source files, anyway.

Problem #2 -

Someone else wrote in to say they get this error message "Class xxx already defined" when they comment out a class definition. If the whole class definition is commented, then error will be generated on class1, class2 and class3 (if they are already loaded by javadoc). package some.package;

import some.class1;
import some.class2;
import some.class3;

/*
public class SupClass {

public void method1() {}

}
*/


Solution #2 -

The solution is: Do not comment out the class definition.

B15. I get the errors "FileNotFoundException" and "Fatal Exception".
Problem - A user encountered the above errors when he tried to build the Javadoc documentation for a package called config. (Solaris operating system, Javadoc 1.2.1) % javadoc -d htm -sourcepath /home/project config

Loading source files for package config...
java.io.FileNotFoundException
at sun.tools.javac.BatchEnvironment.parseFile(Compiled Code)
at com.sun.tools.javadoc.Main.parseSourcePackage(Compiled Code)
at com.sun.tools.javadoc.Main.initInner(Compiled Code)
at com.sun.tools.javadoc.Main.init(Compiled Code)
at com.sun.tools.javadoc.Main.main(Compiled Code)
javadoc: fatal exception
1 error


One symptom was that when he ran javadoc in the directory config and built the documentation for all classes (rather than for the package), there was no error.
% cd config
% javadoc -d ../htm -classpath /home/project *.java
He didn't have a problem with any other package.
Solution - After a lot of sleuthing, he found a (hidden) file called:

.#CreateConfig.java
in the config directory. After removing this file, it worked.
Moral of the Story - Look for stray .java source files that don't belong to the package.

B16. Using Javadoc 1.4.1, I get an InvocationTargetException when I set the classpath.

Using Javadoc 1.4.1, I require that the classpath contain j2ee.jar (for the servlet library), but everytime I add that to the javadoc command, it returns the InvocationTargetException below. javadoc -classpath c:\j2sdkee1.3.1\lib\j2ee.jar -d ..\docs\ *.java

Constructing Javadoc information...
Standard Doclet version 1.4.1

Generating ..\docs\constant-values.html...
Building tree for all the packages and classes...
Building index for all the packages and classes...
Generating ..\docs\overview-tree.html...
Generating ..\docs\index-all.html...
...
Generating ..\docs\AADSHomeServlet.html...
javadoc: In doclet class com.sun.tools.doclets.standard.Standard, method start
has thrown an exception java.lang.reflect.InvocationTargetException
java.lang.NullPointerException
at java.util.zip.ZipFile.getInputStream(ZipFile.java:184)
at com.sun.tools.javadoc.PackageDocImpl.documentation(PackageDocImpl.jav
a:71)
at com.sun.tools.javadoc.DocImpl.comment(DocImpl.java:74)


Solution - Upgrade to Javadoc 1.4.2. Javadoc 1.4.1 has a bug where it tries to read package.html from the jar file without checking if it is really in there. This bug has been fixed in 1.4.2 as 4697040: javadoc is reporting errors when classpath jar files have package.html files.
If you must use 1.4.1, and are forced to put that jar file on the classpath, then open the jar file and put a valid package.html file at the package directory being documented, then jar it back up. For example, if documenting com.package1, then make sure the jar file contains com/package1/package.html.

FYI, the InvocationTargetException is just a wrapper for all exceptions thrown as a result of method invocation -- in this case, the start method. For instance methods, the "target" is an object, and for class methods, the "target" is a class.

B17. Why do I get so many @serial warnings, including warnings about private fields (when I'm not using the -private options)?
There is currently no way to turn off the @serial tag warnings. A future maintenance release will turn the warnings off by default and will only be enabled when you provide a command line option (such as -serialwarn) to javadoc. You can safely ignore the warnings but you cannot turn them off. We can only suggest filtering the warnings out for now.
Any non-static and non-transient field of a Serializable class is considered a serializable field. Any field is serializable, regardless of its access type (public, private or protected). Thus, private Serializable fields require a javadoc comment that includes an @serial tag. Requiring the @serial tag to be added to a default serializable field's doc comment carries the requirement of adding this tag to private fields.

For more information, see Why does the javadoc standard doclet generate many warnings about missing @serial and/or @serialData tags?, which also covers the question "Why do I see javadoc warnings stating that I am missing @serial tags for private fields if I am not running javadoc with the -private switch?".

0 comments: