require-javadoc
This program requires that a Javadoc comment be present on
every Java class, constructor, method, and field.
It does not require a Javadoc comment on methods with an @Override
annotation,
nor on fields named serialVersionUID
.
This tool makes no requirement about the Javadoc comment, beyond its existence.
For example, this tool does not require the existence
of Javadoc tags such as @param
, @return
, etc.
You can use Javadoc itself to enforce such a requirement,
but Javadoc before JDK 18 does not warn
about completely missing comments. In JDK 18+, Javadoc's warnings about
missing comments are not as customizable as this tool is.
Use
Example usage, to check every .java
file in or under the current directory:
java -cp require-javadoc-all.jar org.plumelib.javadoc.RequireJavadoc
Details about invoking the program:
Usage: java org.plumelib.javadoc.RequireJavadoc [options] [directory-or-file ...]
--exclude=<regex> - Don't check files or directories whose pathname matches the regex
--dont-require=<regex> - Don't report problems in Java elements whose name matches the regex
--dont-require-private=<boolean> - Don't report problems in elements with private access [default: false]
--dont-require-noarg-constructor=<boolean> - Don't report problems in constructors with zero formal params [default: false]
--dont-require-trivial-properties=<boolean> - Don't report problems about trivial getters and setters [default: false]
--dont-require-type=<boolean> - Don't report problems in type declarations [default: false]
--dont-require-field=<boolean> - Don't report problems in fields [default: false]
--dont-require-method=<boolean> - Don't report problems in methods and constructors [default: false]
--require-package-info=<boolean> - Require package-info.java file to exist [default: false]
--relative=<boolean> - Report relative rather than absolute filenames [default: false]
--verbose=<boolean> - Print diagnostic information [default: false]
If an argument is a directory, each .java
file in it or its subdirectories will be processed.
With no arguments, require-javadoc
processes all the .java
files in the current directory
or any subdirectory.
The --dont-require
regex is matched against full package names and against simple
(unqualified) names of classes, constructors, methods, and fields.
A constructor with zero arguments is sometimes called a "default constructor", though that term means a no-argument constructor that the compiler synthesized when the programmer didn't write one.
All boolean options default to false, and you can omit the =<boolean>
to set them to true, for
example just --verbose
.
With --dont-require-trivial-properties
, no warnings are issued for code of the following form:
public SomeType getFoo() {
return foo;
}
public void setFoo(SomeType foo) {
this.foo = foo;
}
public boolean isBar() {
return bar;
}
public boolean notBar() {
return !bar;
}
public boolean hasBaz() {
return baz;
}
Incremental use
In continuous integration job (Azure Pipelines, CircleCI, GitHub Actions, or Travis CI),
you can require Javadoc on all changed lines and lines
adjacent to changed lines. This is a way to incrementally get your code
documented, without having to document it all at once.
Here are example commands. (They obtain and use a program
ci-lint-diff
,
which is part of the plume-scripts package.)
if [ -d "/tmp/$USER/plume-scripts" ] ; then
git -C /tmp/$USER/plume-scripts pull -q 2>&1
else
mkdir -p /tmp/$USER && git -C /tmp/$USER/ clone --filter=blob:none -q https://github.com/plume-lib/plume-scripts.git
fi
(./gradlew requireJavadoc > /tmp/warnings.txt 2>&1) || true
/tmp/$USER/plume-scripts/ci-lint-diff /tmp/warnings.txt
Gradle target
To create a requireJavadoc
target, add the following to build.gradle
:
configurations {
requireJavadoc
}
dependencies {
requireJavadoc "org.plumelib:require-javadoc:1.0.6"
}
task requireJavadoc(type: JavaExec) {
group = 'Documentation'
description = 'Ensures that Javadoc documentation exists.'
mainClass = "org.plumelib.javadoc.RequireJavadoc"
classpath = configurations.requireJavadoc
args "src/main/java"
}
check.dependsOn requireJavadoc
You can supply other command-line arguments as well; for example:
...
args "src/main/java", "--dont-require=WeakHasherMap|WeakIdentityHashMap"
javadoc -Xwerror -Xdoclint:all
Comparison to Before JDK 18,
neither require-javadoc
,
nor javadoc -Xwerror -Xdoclint:all
,
nor javadoc -private -Xwerror -Xdoclint:all
,
is stronger.
After JDK 18, require-javadoc
is more configurable.
Therefore, you may want to use all three.
require-javadoc
requires that a Javadoc comment is present, but does not check the content of the comment. For example,require-javadoc
does not complain if an@param
or@return
tag is missing.- Before JDK 18, Javadoc warns about problems in existing Javadoc, but does not warn if
a method is completely undocumented.
With
-private
, it checks private members too. Without-private
, it ensures that public members don't reference private members. Javadoc will complain about missing@param
and@return
tags, but not if@Override
is present. Javadoc does not warn about all Java constructs; for example, it does not process methods within enum constants, nor some private nested classes (even when-private
is supplied). - Starting in JDK 18,
javadoc -Xdoclint:all
produces error messages about missing Javadoc comments. This reduces the need for therequire-javadoc
program. The require-javadoc program is still useful for people who:- are using JDK 17 or earlier
- desire finer-grained control over which program elements must be documented.
-Xdoclint
provides only the key-missing
, which is very coarse. Theci-lint-diff
program is still useful for everyone.require-javadoc
never requires comments on a default constructor, which does not appear in source code, butjavadoc -Xdoclint:all
does, reporting "warning: use of default constructor, which does not provide a comment". To avoid such warnings, you can run javadoc with-Xdoclint:all,-missing
and rely onrequire-javadoc
to warn about missing comments (but not about missing Javadoc tags such as@param
and@return
).
If you want to require all Javadoc tags to be present (a stronger requirement
than require-javadoc
enforces), use the Javadoc tool itself.
From the command line:
javadoc -private -Xwerror -Xdoclint:all
(You should run with and without -private
, since they yield different warnings.
You may wish to adjust the -Xdoclint
argument.)
In a Gradle buildfile, use one of the following (and a similar version to check only public members):
// Turn Javadoc warnings into errors, use strict checking, and process private members.
javadoc {
options.addStringOption('Xwerror', '-Xdoclint:all')
options.addStringOption('private', '-quiet')
}
check.dependsOn javadoc
or
task javadocStrict(type: Javadoc) {
group = 'Documentation'
description = 'Run Javadoc in strict mode: with -Xdoclint:all and -Xwerror, on all members.'
source = sourceSets.main.allJava
classpath = sourceSets.main.runtimeClasspath
options.addStringOption('Xwerror', '-Xdoclint:all')
options.memberLevel = JavadocMemberLevel.PRIVATE
}
check.dependsOn javadocStrict
Comparison to Checkstyle
Checkstyle is configurable to produce the same warnings as require-javadoc
does.
Checkstyle has some problems:
- Checkstyle is heavyweight to run and configure: configuring it requires multiple files.
- Checkstyle is nondeterministic: it gives different results for file
A.java
depending on what other files are being checked. - Checkstyle crashes on correct code. For example, see checkstyle/checkstyle#5989, which the maintainers closed as "checkstyle does not support it by design".
By contrast to Checkstyle, require-javadoc
is easier to use, and it actually works.