Что мне нужно для сборки проекта JDK 9 с немодулярными зависимостями с использованием Maven
У меня есть простой проект Java 9 SE с одной зависимостью от немодулярного проекта (в этом примере я выбрал Weld SE), и я пытаюсь построить его с помощью Maven (clean install
). Для того, чтобы Java 9 заработала, я добавил module-info.java
, Первоначально этот файл содержал только имя модуля и не имел requires
формулы.
Пожалуйста, имейте в виду, что моя единственная зависимость НЕ является модульным проектом, поэтому я предположил, что Maven вставит classpath (не module-path) и, следовательно, он окажется в unnamed module
как описано в состоянии модульной системы.
Теперь моя версия Maven 3.3.9, и я знаю, что мне нужно использовать плагин компилятора Maven в версии 3.6, как описано здесь. Конечно, я скачал сборку JDK 9 EA с Jigsaw и настроил Maven для ее использования.
Если я построю свой проект без module-info.java
все работает, материал добавляется в classpath и сборка завершается успешно. Я полагаю, что Maven просто придерживается старых способов, пока вы пропустите этот файл.
Однако строить его с module-info.java
говорит мне, что классы из моей зависимости не могут быть найдены на пути к классам. Итак, я запустил Maven в режиме отладки (с -X) и действительно - все jar-файлы находятся в модуле path, а classpath пуст Это фактически означает, что все мои зависимости передаются в автоматические модули, и мне нужно объявить их в module-info.java
,
Однажды я объявляю требования к автоматическому модулю (ссылка на проекты module-info
), Я могу построить его на JDK 9. Но это немного грязно - мой единственный pom.xml
зависимость от weld-se-core
все же мой module-info
требует, чтобы я объявил намного больше требований для прохождения компиляции.
Вот целый проект GitHub, где все это можно наблюдать.
Итак, мои вопросы:
- Могу ли я сказать Maven поместить некоторые артефакты в путь к классам, если я знаю, что они не являются модульными? Так что я могу избежать
automatic module
а нужно их декларировать? - Если я буду придерживаться
automatic module
Могу ли я сказать Maven как-то транзитивно разрешить что-нибудь, что моя зависимость должна принести? Например, другие части Weld, CDI API и т. Д. - Какова реальная причина, почему я должен заявить, что мой проект
requires
модули, которые я не использую напрямую? Напримерweld.environment.common
3 ответа
Включая несколько последних обновлений, я постараюсь ответить на это.
ОБНОВИТЬ
- Java 9 была выпущена публично 21.09.2017.
Минимальная совместимая версия
maven-compiler-plugin
на сегодняшний день3.7.0
,Как уже сообщал @Tunaki, о том, как вы можете настроить его для создания совместимых версий для JDK 1.5–8 и JDK 9.
Исходя из вопроса и комментариев, вы уже знаете об автоматических модулях и размещаете все зависимости модулей на пути к модулю.
Могу ли я сказать Maven поместить некоторые артефакты в путь к классам, если я знаю, что они не являются модульными? Так что я могу избежать автоматического модуля и необходимости объявлять их?
Для артефактов, указанных в Maven POM <dependencies>
и те, которые также не включены в module-info.java
текущего модуля в конечном счете оставлены для доступа из classpath в виде неназванного модуля.
Если я остановлюсь на автоматическом модуле, могу ли я сказать Maven как-то транзитивно разрешить что-либо, что моя зависимость должна внести? Например, другие части Weld, CDI API и т. Д.
Нет, поскольку автоматические модули не состоят из явно объявленных module-info.java
нет такого способа определения requires transitive
для любой переходной зависимости, которая может потребоваться для данного модуля.
Из одного из моих прошлых опытов, любая переходная зависимость Maven, как подробно описано в dependency:tree
то, что необходимо модулю во время компиляции, должно быть явно определено с помощью requires
в module-info
текущего проекта.
Какова реальная причина, почему я должен заявить, что мой проект требует модулей, которые я не использую напрямую? Например, weld.environment.common**
Вам не нужно указывать
requires
для модулей, которые не требуются при компиляции или во время выполнения вашим модулем.В случае, если есть зависимость, которая не требуется во время выполнения, но требуется во время компиляции вашим проектом, вам необходимо убедиться, что вы определяете такой модуль, используя
requires static
в ваших декларациях.Я бы предпочел также практиковать аналогичный подход в настоящее время, как указано в ответе, должен ли я сохранить или удалить объявленные зависимости, которые также являются транзитивными зависимостями?
Я думаю, что это может помочь Maven использовать Java 9:
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>9</source>
<target>9</target>
</configuration>
</plugin>
</plugins>
</build>
Если вы укажете module-info.java
файл, вам нужно будет объявить все Java-модули, кроме java.base
вам нужно, как вы сейчас используете головоломки.
С помощью mvn dependency:tree
может помочь вам в заполнении этого, но вы не обязаны использовать module-info.java
в Java 9.