I've been using the Maven Javadoc Plugin javadoc:jar
goal for years, publishing many Java artifacts to Nexus (Maven Central). Currently I'm using Maven 3.8.6 with Java 17, and org.apache.maven.plugins:maven-javadoc-plugin:3.4.1
.
Today I'm reading the plugin documentation (emphasis in the documentation):
javadoc:jar
: "Bundles the Javadoc documentation for main Java code
in an NON aggregator project into a jar using the standard Javadoc Tool."javadoc:aggregate-jar
: "Bundles the Javadoc documentation for main Java code
in an aggregator project into a jar using the standard Javadoc Tool."javadoc:aggregate-no-fork
: "Generates documentation for the Java code
in an aggregator project using the standard Javadoc Tool."This confuses me a bit. What does the documentation mean when it refers to an "aggregator project"? Is it referring to a project using an aggregate POM, in which the parent POM lists several sub-project POMs being aggregated? Yet why would it make a difference which Maven Javadoc Plugin goal is used?
For years I have set up the Maven Javadoc Plugin in a "root POM" for all my projects. It uses the javadoc:jar
goal. It sets up the plugin configuration for the child projects which inherit from it. Some of the child projects are standalone single-POM projects. Some of them are aggregate POMs. I've never had a problem doing it this way.
Should I be using the javadoc:jar
goal for some projects, and the javadoc:aggregate-jar
for other projects? But how could the root POM even know whether the child project is an aggregate project or not? What will break if I continue using the javadoc:jar
goal for everything?
(As bonus, what is this separate javadoc:aggregate-no-fork
goal?)
Yes, "aggregator project" refers to project aggregation. Using javadoc:jar
or javadoc:aggregate-jar
results in different outputs:
Running javadoc:jar
on the parent recursively executes on all modules, as you can see in the output:
[INFO] Building parent 0.0.0-SNAPSHOT [1/3]
...
[INFO] Not executing Javadoc as the project is not a Java classpath-capable package
...
[INFO] Building module1 0.0.0-SNAPSHOT [2/3]
...
[INFO] Building jar: /module1/target/module1-0.0.0-SNAPSHOT-javadoc.jar
...
[INFO] Building module2 0.0.0-SNAPSHOT [3/3]
...
[INFO] Building jar: /module2/target/module2-0.0.0-SNAPSHOT-javadoc.jar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for parent 0.0.0-SNAPSHOT:
[INFO]
[INFO] parent ............................................. SUCCESS [ 0.942 s]
[INFO] module1 ............................................ SUCCESS [ 1.154 s]
[INFO] module2 ............................................ SUCCESS [ 1.126 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
Separate Javadoc outputs are created in the target
folders of each module and bundled into separate JARs.
Running javadoc:jar
only on the parent using --non-recursive
will not output anything.
On the other hand, the execution of javadoc:aggregate-jar
runs only on the parent:
[INFO] Building parent 0.0.0-SNAPSHOT [1/3]
...
[INFO] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[INFO] Forking module1 0.0.0-SNAPSHOT
[INFO] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
...
[INFO] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
[INFO] Forking module2 0.0.0-SNAPSHOT
[INFO] >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
...
[INFO] Building jar: /target/parent-0.0.0-SNAPSHOT-javadoc.jar
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for parent 0.0.0-SNAPSHOT:
[INFO]
[INFO] parent ............................................. SUCCESS [ 2.971 s]
[INFO] module1 ............................................ SKIPPED
[INFO] module2 ............................................ SKIPPED
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
Javadoc is only created in one place at the parent's /target/apidocs
, bundled into a single JAR.
The Javadoc plugin is skipped for the modules, but the parent execution creates forked builds executing the compile
phase for each module, to make sure all input for the Javadoc processing is present (i.e. generated sources).
Running javadoc:aggregate-no-fork
on the parent does not create forked builds but recursively runs on each module generating Javadocs...
[INFO] Building parent 0.0.0-SNAPSHOT [1/3]
...
[INFO] No previous run data found, generating javadoc.
...
[INFO] Building module1 0.0.0-SNAPSHOT [2/3]
...
[INFO] No previous run data found, generating javadoc.
...
[INFO] Building module2 0.0.0-SNAPSHOT [3/3]
...
[INFO] No previous run data found, generating javadoc.
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary for parent 0.0.0-SNAPSHOT:
[INFO]
[INFO] parent ............................................. SUCCESS [ 1.909 s]
[INFO] module1 ............................................ SUCCESS [ 1.082 s]
[INFO] module2 ............................................ SUCCESS [ 0.991 s]
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
...and also aggregates them into the parent's /target/site/apidocs
. This command is intended to be used in CI environments where all sources already have been prepared.
In contrast to the previous commands, no JARs are created.