У меня есть многомодульный проект 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
. Настроив плагин surefire в конфигурации jdrum
с помощью приведенного ниже фрагмента кода, я могу без проблем упаковать весь проект.
<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 соответствующих проектов. Конфигурация JAR-файла, содержащего javadoc, а также конфигурация для генерации 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. Поэтому следующим логическим шагом было добавить этот модуль в конфигурацию как таковой:
<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 напрямую этого не позволяет. Поэтому я придумал добавить дополнительную опцию maven-javadoc-plugin --module-path
и дополнительную запись опции, содержащую весь путь. Под полным путем я подразумеваю путь к каждой отдельной зависимости, а не только путь к jdrum-datastore-simple
. Это также работает, но из-за того, что путь к соответствующим файлам JAR жестко запрограммирован, проект теперь не может использоваться другими пользователями, если у них нет той же системы и структуры пути, которые я использовал. Чтобы исправить это, я быстро заменил соответствующую структуру пути на свойства ${settings.localRepository}
и ${project.parent.basedir}
соответствующих модулей в пути к модулю. К сожалению, Javadoc довольно придирчив к структуре пути, которую он принимает, и оказывается, что на моей машине с Windows Maven действительно возвращает структуру пути, начинающуюся с C:\Users\...
, которую Javadoc не может обработать. Если структура пути выглядит как C:/Users/...
, однако Javadoc в порядке со значениями.
В ходе дальнейших исследований я наткнулся на этот поток, в котором предлагается использовать build-helper-maven-plugin
Maven для определения новых свойств, например, репозитория M2, и использовать встроенную возможность регулярного выражения для замены символов \
на /
. Однако добавление такой конфигурации, как
<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 не может разрешить и, следовательно, все еще пропускает out в правильном месте к зависимости jdrum-datastore-simple
.
Итак, как я могу добавить путь к отсутствующей зависимости к пути модуля maven-javadoc-plugin, определенному в сгенерированном файле параметров, чтобы Maven действительно мог сгенерировать весь отчет?