Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

maven-javadoc-plugin and inheritDoc for Java API core classes

I am writing my own Java 8 Stream implementation and want to inherit the Javadocs from the original java.util.stream.Stream interface. However I cannot get it working. The generated Javadoc does only show my documentation but not the documentation from the extended Stream interface.

So for example, the javadoc of this method does only contain the text "Some additional information" but not the documentation from the Stream interface.

/**
 * {@inheritDoc}
 * Some additional information.
 */
@Override
public Stream<T> filter(Predicate<? super T> predicate) {
  // ... my stream implementation...
}

This is my configuration of the maven-javadoc-plugin:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-javadoc-plugin</artifactId>
  <version>2.10.1</version>
  <configuration>
    <links>
      <link>http://docs.oracle.com/javase/8/docs/api/</link>
    </links>
  </configuration>
</plugin>

Do I miss something in this configuration? I set source and target to 1.8 in the maven-compiler-plugin. So according to the documentation of the maven-javadoc-plugin, the java API should be detected automatically.

There was also a similar question on Stack Overflow but the answers there do not seem helpful.

like image 616
Stefan Ferstl Avatar asked Aug 01 '16 19:08

Stefan Ferstl


2 Answers

That is expected, javadoc only copies comments from classes that are inside the source path. From Method Comment Inheritance:

Note: The source file for an inherited method must be on the path specified by the -sourcepath option for the documentation comment to be available to copy. Neither the class nor its package needs to be passed in on the command line. This contrasts with Release 1.3.n and earlier releases, where the class had to be a documented class.

However, the sources of your JDK aren't in the source path, so {@inheritDoc} won't copy it. They need to be added explicitely; the Javadoc FAQ has this entry:

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.

So, to make it work:

  1. Locate the sources of your JDK and unzip them somewhere.
  2. Configure the maven-javadoc-plugin to add those sources with the sourcepath parameter.
  3. With the above, we would also generate the Javadoc of the JDK itself, which is unnecessary (we only want to inherit), so we can use subpackages to specify only our packages. Alternatively, we can use excludePackageNames to exclude the JDK packages.
  4. The JDK (at least Oracle JDK) also uses new Javadoc entries, namely @apiNote, @implSpec and @implNote. Those are custom tags that need to be added with the tags parameter.

Here's a sample configuration, where the path to the JDK sources is /path/to/jdk/sources (you could also use an environment variable, a property set by profile, etc.) and your own source files are all in the package my.package:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>2.10.1</version>
    <configuration>
        <sourcepath>/path/to/jdk/sources:${basedir}/src/main/java</sourcepath>
        <subpackages>my.package</subpackages>
        <tags>
            <tag>
                <name>apiNote</name>
                <placement>a</placement>
                <head>API Note:</head>
            </tag>
            <tag>
                <name>implSpec</name>
                <placement>a</placement>
                <head>Implementation Requirements:</head>
            </tag>
            <tag>
                <name>implNote</name>
                <placement>a</placement>
                <head>Implementation Note:</head>
            </tag>
        </tags>
    </configuration>
</plugin>

Generating the Javadoc, for example with mvn javadoc:javadoc, will correctly resolve the {@inheritDoc}.

like image 179
Tunaki Avatar answered Sep 29 '22 10:09

Tunaki


Tunaki's answer is great but as of Java 10 you have an even better option. If you pass --override-methods=summary to the Javadoc tool it'll push all inherited methods down to a "Methods declared in class X" section down below. This will list the inherited methods. Clicking on method names will take the user to the Javadoc definition in the base class.

See https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8187386 for background information.

like image 27
Gili Avatar answered Sep 29 '22 10:09

Gili