maven-javadoc-plugin:如何动态更新模块路径
maven-javadoc-plugin: How to update the module path dynamically
我有一个 Java (11.0.7) Maven (3.0.6) 多模块项目,其中包含以下模块声明:
<modules>
<module>jdrum-commons</module>
<module>jdrum-datastore-base</module>
<module>jdrum-datastore-simple</module>
<module>jdrum</module>
</modules>
这些 Maven 模块中的每一个都包含一个 module-info
,它定义了必要的要求和导出以限制访问和可见性。
因此,jdrum-datastore-simple
有一些我在 jdrum
的测试中重复使用的测试实用程序 类。通过下面的代码片段在 jdrum
的配置中配置 surefire 插件,我可以毫无问题地打包整个项目。
<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>
在父 POM 中,我还通过 site
参数配置了报告的生成,该参数还生成了各个项目的 Javadoc。包含 javadoc 的 JAR 的配置以及作为报告一部分的 Javadoc 生成的配置都是相同的,如下所示:
<!-- 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>
Javadoc 生成作为 package
步骤的一部分,它生成 project-version-javadoc.jar
作为输出,因为 jdrum-datastore-simple
依赖项及其测试,仅在测试时包含:
<!-- 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>
如果我将范围从 test
更改为 compile
或 provided
,Javadoc 生成也会失败并出现错误,例如
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.
据我了解,这里的问题是 jdrum-datastore-simple
模块没有添加到 Javadoc 的模块路径中。因此,下一个合乎逻辑的步骤是add that module to the configuration:
<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>
这会将 jdrum-datastore-simple
模块添加到 Javadoc 配置字符串,可以在现在包含
的 jdrum/target/site/apidocs/options
文件中看到
...
--add-modules
jdrum.datastore.simple
...
条目。在进一步分析生成的 options
文件时,很明显模块路径缺少对实际 JAR 文件的引用,因此缺少 Javadoc 生成,因此 Maven 进程因 Javadoc 无法找到定义的模块。如果我更新该选项文件并将路径添加到丢失的 JAR 文件,然后只执行 mvn package site
整个过程成功并且一切正常(因为 javadoc.bat 的纯调用位于 target/site/apidocs 文件夹也是如此)。
现在,为了使整个过程更加动态,我想添加或更新模块路径。然而,maven-javadoc-plugin 并没有直接允许这样做。因此,我想出了添加 --module-path
的进一步 maven-javadoc-plugin 选项和包含整个路径的进一步选项条目。我所说的整个路径是指每个依赖项的路径,所以不仅仅是 jdrum-datastore-simple
的路径。这也有效,但由于对各自 JAR 文件的路径进行硬编码,该项目现在不能被其他用户使用,除非他们具有我使用的相同系统和路径结构。为了解决这个问题,我迅速用模块路径中各个模块的 ${settings.localRepository}
和 ${project.parent.basedir}
属性替换了各自的路径结构。不幸的是,Javadoc 对它接受的路径结构相当挑剔,事实证明在我的 Windows 机器上 Maven 做了 return 一个以 C:\Users\...
开头的路径结构,Javadoc 无法处理。如果路径结构看起来像 C:/Users/...
,但是 Javadoc 的值没问题。
在进一步的研究中,我偶然发现了 this thread,它建议使用 Maven 的 build-helper-maven-plugin
来定义新属性,即 M2 存储库,并使用内置的 reg-ex 功能来替换 \
个字符 /
。但是,添加配置如
<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>
并且使用引入的标签根本不起作用,因为 Maven 抱怨提供的值无效。如果我使用 $\{settings.localRepository}
Maven 对提供的值很好,但是在最终的选项文件中,实际 settings.localRepository
的值没有更新,而是提供的字符串本身,我最终得到类似 $/{settings.localRepository}/org/slf4j/...
Javadoc 无法解析,因此仍然错过 jdrum-datastore-simple
依赖项的正确位置。
那么,如何将缺少的依赖项的路径添加到生成的选项文件中定义的 maven-javadoc-plugin 模块路径,以便 Maven 实际上能够生成整个报告?
似乎 java11 Update 9
(也许还有更新 8;未测试)maven-javadoc-plugin 能够为多模块项目正确生成 Javadoc,而无需更改模块路径.
对于那些对实际 Maven POM 的样子感兴趣的人:
我有一个 Java (11.0.7) Maven (3.0.6) 多模块项目,其中包含以下模块声明:
<modules>
<module>jdrum-commons</module>
<module>jdrum-datastore-base</module>
<module>jdrum-datastore-simple</module>
<module>jdrum</module>
</modules>
这些 Maven 模块中的每一个都包含一个 module-info
,它定义了必要的要求和导出以限制访问和可见性。
因此,jdrum-datastore-simple
有一些我在 jdrum
的测试中重复使用的测试实用程序 类。通过下面的代码片段在 jdrum
的配置中配置 surefire 插件,我可以毫无问题地打包整个项目。
<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>
在父 POM 中,我还通过 site
参数配置了报告的生成,该参数还生成了各个项目的 Javadoc。包含 javadoc 的 JAR 的配置以及作为报告一部分的 Javadoc 生成的配置都是相同的,如下所示:
<!-- 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>
Javadoc 生成作为 package
步骤的一部分,它生成 project-version-javadoc.jar
作为输出,因为 jdrum-datastore-simple
依赖项及其测试,仅在测试时包含:
<!-- 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>
如果我将范围从 test
更改为 compile
或 provided
,Javadoc 生成也会失败并出现错误,例如
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.
据我了解,这里的问题是 jdrum-datastore-simple
模块没有添加到 Javadoc 的模块路径中。因此,下一个合乎逻辑的步骤是add that module to the configuration:
<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>
这会将 jdrum-datastore-simple
模块添加到 Javadoc 配置字符串,可以在现在包含
jdrum/target/site/apidocs/options
文件中看到
...
--add-modules
jdrum.datastore.simple
...
条目。在进一步分析生成的 options
文件时,很明显模块路径缺少对实际 JAR 文件的引用,因此缺少 Javadoc 生成,因此 Maven 进程因 Javadoc 无法找到定义的模块。如果我更新该选项文件并将路径添加到丢失的 JAR 文件,然后只执行 mvn package site
整个过程成功并且一切正常(因为 javadoc.bat 的纯调用位于 target/site/apidocs 文件夹也是如此)。
现在,为了使整个过程更加动态,我想添加或更新模块路径。然而,maven-javadoc-plugin 并没有直接允许这样做。因此,我想出了添加 --module-path
的进一步 maven-javadoc-plugin 选项和包含整个路径的进一步选项条目。我所说的整个路径是指每个依赖项的路径,所以不仅仅是 jdrum-datastore-simple
的路径。这也有效,但由于对各自 JAR 文件的路径进行硬编码,该项目现在不能被其他用户使用,除非他们具有我使用的相同系统和路径结构。为了解决这个问题,我迅速用模块路径中各个模块的 ${settings.localRepository}
和 ${project.parent.basedir}
属性替换了各自的路径结构。不幸的是,Javadoc 对它接受的路径结构相当挑剔,事实证明在我的 Windows 机器上 Maven 做了 return 一个以 C:\Users\...
开头的路径结构,Javadoc 无法处理。如果路径结构看起来像 C:/Users/...
,但是 Javadoc 的值没问题。
在进一步的研究中,我偶然发现了 this thread,它建议使用 Maven 的 build-helper-maven-plugin
来定义新属性,即 M2 存储库,并使用内置的 reg-ex 功能来替换 \
个字符 /
。但是,添加配置如
<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>
并且使用引入的标签根本不起作用,因为 Maven 抱怨提供的值无效。如果我使用 $\{settings.localRepository}
Maven 对提供的值很好,但是在最终的选项文件中,实际 settings.localRepository
的值没有更新,而是提供的字符串本身,我最终得到类似 $/{settings.localRepository}/org/slf4j/...
Javadoc 无法解析,因此仍然错过 jdrum-datastore-simple
依赖项的正确位置。
那么,如何将缺少的依赖项的路径添加到生成的选项文件中定义的 maven-javadoc-plugin 模块路径,以便 Maven 实际上能够生成整个报告?
似乎 java11 Update 9
(也许还有更新 8;未测试)maven-javadoc-plugin 能够为多模块项目正确生成 Javadoc,而无需更改模块路径.
对于那些对实际 Maven POM 的样子感兴趣的人: