Search code examples
javamavenmaven-javadoc-plugin

How to make Maven Javadoc Plugin work with any Java version


I'm using Maven Javadoc Plugin like this

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>3.1.1</version>
    <executions>
        <execution>
            <id>attach-javadocs</id>
            <goals>
                <goal>jar</goal>
            </goals>
        </execution>
    </executions>
</plugin>

I have multiple JDK versions installed and want to be able to build a project with any of them. The above configuration works fine with Java 8, but it fails with Java 11 with the following error

Failed to execute goal org.apache.maven.plugins:maven-javadoc-plugin:3.1.1:jar (attach-javadocs) on project ...: MavenReportException: Error while generating Javadoc: Unable to find javadoc command: The environment variable JAVA_HOME is not correctly set.

The obvious solution is to set JAVA_HOME. But as I mentioned, I have multiple versions of JDK, so reconfiguring JAVA_HOME every time I want to use another version wouldn't be convenient at all.

Another solution (from Unable to find javadoc command - maven) is to add the following configuration to the plugin:

<configuration>
    <javadocExecutable>${java.home}/bin/javadoc</javadocExecutable>
</configuration>

This makes it work with Java 11, but breaks Java 8 because the javadoc location is ${java.home}/../bin/javadoc in that case.

Ideally I always want to use javadoc from the directory where the java executable that Maven uses is, but I haven't found a way to do it with Maven Javadoc Plugin.


Solution

  • Maven profiles may be able to help.

    Add something like this to your POM.

    <profiles>
        <profile>
            <id>jdk-8-config</id>
            <activation>
                <jdk>1.8</jdk>
            </activation>
            <properties>
                <javadocExecutable>${java.home}/../bin/javadoc</javadocExecutable>
            </properties>
        </profile>
        <profile>
            <id>jdk-11-config</id>
            <activation>
                <jdk>11</jdk>
            </activation>
            <properties>
                <javadocExecutable>${java.home}/bin/javadoc</javadocExecutable>
            </properties>
        </profile>
    </profiles>
    

    JDK ranges are also possible, read more on those in the linked doc.

    Maven will pick up the version of Java being used to run itself, activate the correct profile, and define the property correct.

    A caveat - typically we build with JAVA_HOME set, or via Jenkins which can be configured to define JAVA_HOME per job. This approach works well in those cases.

    You could also investigate Maven toolchains. I have no experience with those, other than reading they help make it easier to define tool locations on various machines.