maven-javadoc-plugin: как динамически обновлять путь к модулю

У меня есть многомодульный проект 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 действительно мог сгенерировать весь отчет?


person Roman Vottner    schedule 05.06.2020    source источник


Ответы (1)


Похоже, что с java11 Update 9 (возможно, также с обновлением 8; не тестировалось) maven-javadoc-plugin может правильно генерировать Javadoc для многомодульных проектов без необходимости изменять путь к модулю.

Для тех, кому интересно, как выглядит реальный Maven POM:

person Roman Vottner    schedule 22.12.2020