简体   繁体   中英

maven-javadoc-plugin: How to update the module path dynamically

I have a Java (11.0.7) Maven (3.0.6) multi-module project that contains the following module declarations:

<modules>
    <module>jdrum-commons</module>
    <module>jdrum-datastore-base</module>
    <module>jdrum-datastore-simple</module>
    <module>jdrum</module>
</modules>

Each of these Maven modules contains a module-info that defines the necessary requirements and exports to restrict access and visibility.

As such, jdrum-datastore-simple has some test utility classes that I reuse in jdrum 's tests. By configuring the surefire plugin in jdrum 's config via the code snippet below I am able to package the whole project without any issues.

<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <argLine>
                    <!-- Allow the unnamed module access to the tests at test-time -->
                    --add-opens jdrum/at.rovo.drum.impl=ALL-UNNAMED
                    --illegal-access=deny
                </argLine>
            </configuration>
        </plugin>
    </plugins>
</build>

Within the parents POM I've also configured the generation of a report via the site argument, which also generates the Javadoc of the respective projects. The configuration for the JAR containing the javadoc as well as the configuration for the Javadoc generation as part of the report are both the same and look like this:

<!-- Generate Javadoc while reporting -->
<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-javadoc-plugin</artifactId>
    <version>3.2.0</version>
    <inherited>true</inherited>
    <configuration>
        <verbose>true</verbose>
        <source>${maven.compiler.source}</source>
        <show>protected</show>
        <failOnWarnings>false</failOnWarnings>
        <release>${maven.compiler.release}</release>
        <stylesheet>java</stylesheet>
    </configuration>
    <reportSets>
        <reportSet>
            <id>html</id>
            <reports>
                <report>javadoc</report>
            </reports>
        </reportSet>
    </reportSets>
</plugin>

The Javadoc generation as part of the package step, which generates the project-version-javadoc.jar as output, succeeds as both, the jdrum-datastore-simple dependencies as well as its tests, are only included at test time:

<!-- Test data store to use for testing -->
<dependency>
    <groupId>at.rovo</groupId>
    <artifactId>jdrum-datastore-simple</artifactId>
    <version>${project.parent.version}</version>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>at.rovo</groupId>
    <artifactId>jdrum-datastore-simple</artifactId>
    <version>${project.parent.version}</version>
    <scope>test</scope>
    <type>test-jar</type>
</dependency>

If I'd change the scope from test to compile or provided the Javadoc generation would also fail with an error such as

Exit code: 1 - javadoc: error - The code being documented uses packages in the unnamed module, but the packages defined in https://github.com/RovoMe/JDrum/jdrum-datastore-simple/apidocs/ are in named modules.

The issue here, as far as I understood the problem, is, that the jdrum-datastore-simple module is not added to the module path of Javadoc. The next logical step was therefore to add that module to the configuration as such:

<reporting>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-javadoc-plugin</artifactId>
            <configuration>
                <additionalOptions>
                    <option>--add-modules</option>
                    <option>jdrum.datastore.simple</option>
                </additionalOptions>
            </configuration>
        </plugin>
    </plugins>
</reporting>

This adds the jdrum-datastore-simple module to the Javadoc configuration string, which can be seen in the jdrum/target/site/apidocs/options file that now contains an

...
--add-modules
jdrum.datastore.simple
...

entry. On further analyzing the generated options file it is apparent that the module path is missing out a reference to the actual JAR file and hence the Javadoc generation and thus the Maven process fails due to Javadoc not being able to locate the defined module. If I update that options file and add the path to the missing JAR file and then only perform a mvn package site the whole process succeeds and all is fine (as the pure invocation of the javadoc.bat located in the target/site/apidocs folder would as well).

Now, in order to make the whole process more dynamic I wanted to add or update the module path. However, the maven-javadoc-plugin does not directly allow this. Therefore I came up with adding a further maven-javadoc-plugin option of --module-path and a further option entry that contains the whole path. By the whole path I mean the path to every single dependency, so not only the path to jdrum-datastore-simple . This also works but due to hardcoding the path to the respective JAR files, the project is now not usable by other users unless they have the same system and path structure I used. To fix this I quickly replaced the respective path structure with ${settings.localRepository} and ${project.parent.basedir} properties on the respective modules in the module path. Unfortunately Javadoc is rather nitpicking on the path structure it accepts and it turns out that on my Windows machine Maven does return a path structure starting with C:\Users\... which Javadoc can't handle. If the path structure looks like C:/Users/... however Javadoc is fine with the values.

On further research I stumbled upon this thread which suggests to use Maven's build-helper-maven-plugin to define new properties for ie the M2 repository and use the built-in reg-ex capability to replace \ characters with / . However, adding a configuration such as

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>build-helper-maven-plugin</artifactId>
    <version>3.1.0</version>
    <executions>
        <execution>
            <id>replace-local-repo-characters</id>
            <goals>
                <goal>regex-property</goal>
            </goals>
            <configuration>
                <name>tag.m2repo</name>
                <value>${settings.localRepository}</value>
                <regex>\\</regex>
                <replacement>/</replacement>
                <failIfNoMatch>false</failIfNoMatch>
            </configuration>
        </execution>
        <execution>
            <id>replace-local-path-characters</id>
            <goals>
                <goal>regex-property</goal>
            </goals>
            <configuration>
                <name>tag.basedir</name>
                <value>${project.parent.basedir}</value>
                <regex>\\</regex>
                <replacement>/</replacement>
                <failIfNoMatch>false</failIfNoMatch>
            </configuration>
        </execution>
    </executions>
</plugin>

and using the introduced tags instead does not work at all as Maven is complaining about an invalid value provided. If I use $\{settings.localRepository} Maven is fine about the provided value, however in the final options file not the value of the actual settings.localRepository is updated but the provided string itself and I end up with something like $/{settings.localRepository}/org/slf4j/... which Javadoc can't resolve and therefore still misses out on the correct location to the jdrum-datastore-simple dependency.

So, how can I add the path to the missing dependency to maven-javadoc-plugin's module path defined in the generated options file so that the Maven is actually able to generate the whole report?

It seems that with java11 Update 9 (maybe also with update 8; not tested) maven-javadoc-plugin is able to correctly generate the Javadoc for multi-module projects without the need to alter the module-path.

For those interested how the actual Maven POM looks like:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM