Adventures With Javadocs (Part 1)
Part of publishing high-quality libraries is providing high-quality documentation, which in Android-land means: high-quality Javadocs. There are tons of good resources around that explain proper Javadoc comment format and content, so in this series we’ll explore the actual generation of documentation using Gradle/Android Studio.
Javadoc Task Type Basics
The Gradle Java plugin provides a template Javadoc task with the following description:
Generates HTML API documentation for Java classes.
If you create your own Javadoc tasks remember to specify the ‘source’ property! Without source the Javadoc task will not create any documentation.
For an Android library project, the simplest configuration of this task would therefore be:
apply plugin: 'com.android.library'
android {
compileSdkVersion 23
buildToolsVersion "23.0.2"
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
versionName "1.0.0"
}
}
task docs(type: Javadoc) {
source = android.sourceSets.main.java.srcDirs
}
[This assumes a project with no other dependencies, no flavor/type/variant-specific source files, etc.]
Let’s add a super-simple pair of test classes to the project, each in their own package:
package com.github.stkent.javadoctests.package1;
/**
* This class depends on an automatically-imported type only!
*/
public class TestClassOne {
private String string;
public TestClassOne(String string) { this.string = string; }
public String getString() { return string; }
}
package com.github.stkent.javadoctests.package2;
import com.github.stkent.javadoctests.package1.TestClassOne;
/**
* This class depends on a user-created and -imported type only!
*/
public class TestClassTwo {
private TestClassOne testClassOne;
public TestClassTwo(TestClassOne testClassOne) { this.testClassOne = testClassOne; }
public TestClassOne getTestClassOne() { return testClassOne; }
}
and generate Javadocs by executing our new docs
task:
./gradlew library:clean library:docs
which produces the following output files:

Note in particular that the directory structure of the generated website matches the package structure of the original source files. For example, the class TestClassOne
is part of the com.github.stkent.javadoctests.package1
package, and its corresponding documentation page is inside the com/github/stkent/javadoctests/package1 subdirectory of the generated website.
Generated Documentation
Before proceeding, I’d like to review a pair of sample pages from this output. This will provide some important context for the next post in this series.
Here’s the summary generated for TestClassOne
:

and the corresponding summary generated for TestClassTwo
:

The TestClassTwo
constructor signature includes a hyperlink to the generated documentation page for its lone parameter type (TestClassOne
). Based on the correspondence between directory structure and package structure we identified earlier, I would postulate that the javadoc
tool generates this link by parsing the following import statement in TestClassTwo
:
import com.github.stkent.javadoctests.package1.TestClassOne;
On the other hand, because the Java String
type is not part of the source we provided to the docs
task, the javadoc
tool has no way of determining an equivalent hyperlink target to use for the TestClassOne
constructor parameter type.
Under The Hood
Gradle’s Javadoc task type acts as a wrapper around the command-line javadoc
tool included with every JDK. To locate yours, run which javadoc
from the command line (the path to this file should match your JAVA_HOME
environment variable, if set):
$ which javadoc
/Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/bin/javadoc
The temporary javadoc.options file generated by our Gradle task contains options and arguments that are forwarded to this command-line tool. For our example, the javadocs.options file contains these lines:
-d '/Users/stuart/dev/personal/libraries/JavadocTests/library/build/docs/javadoc'
-doctitle 'library API'
-quiet
-windowtitle 'library API'
'/Users/stuart/dev/personal/libraries/JavadocTests/library/src/main/java/com/github/stkent/javadoctests/package1/TestClassOne.java'
'/Users/stuart/dev/personal/libraries/JavadocTests/library/src/main/java/com/github/stkent/javadoctests/package2/TestClassTwo.java'
This is pretty minimal configuration - we are setting the output directory, titles to use for the generated website, and providing the collection of source files for which we would like documentation to be generated. To confirm the claim that Gradle’s Javadoc task calls javadoc
with these options and arguments, we can run:
./gradlew library:clean
followed by:
javadoc -d '/Users/stuart/dev/personal/libraries/JavadocTests/library/build/docs/javadoc' -doctitle 'library API' -quiet -windowtitle 'library API' '/Users/stuart/dev/personal/libraries/JavadocTests/library/src/main/java/com/github/stkent/javadoctests/package1/TestClassOne.java' '/Users/stuart/dev/personal/libraries/JavadocTests/library/src/main/java/com/github/stkent/javadoctests/package2/TestClassTwo.java'
which produces the output files shown below (viewed within Android Studio):

This is identical to the output of the Gradle task itself, minus the temporary javadoc.options file! Which is neat, because it means we can leverage all the existing javadoc
tool documentation to help us overcome some of the challenges we’ll be facing in the next post, in which we add classes from the Android framework and third-party dependencies to our sample project.
The code for this post is available here.