Что значит "Обнаружены обязательные автомодули на основе имени файла". предупреждение значит?
В моем многомодульном проекте я создал module-info.java
только для нескольких модулей. И во время компиляции с maven-compiler-plugin:3.7.0
Я получаю следующее предупреждение:
[ПРЕДУПРЕЖДЕНИЕ] * Обязательные авто-модули на основе имени файла обнаружены. Пожалуйста, не публикуйте этот проект в публичном хранилище артефактов! *
Что это значит? Это потому, что у меня есть только несколько модулей с module-info.java
а не весь проект?
4 ответа
Автоматический пересчет модуля
Явный модуль (т. Е. Один с module-info.java
) может получить доступ только к коду модулей, которые ему требуются (на мгновение игнорируя подразумеваемую читаемость). Прекрасно, если все зависимости являются модульными, но что, если это не так? Как обратиться к JAR, который не является модульным?
Автоматические модули - это ответ: любой JAR, который попадает на путь модуля, превращается в модуль. Если JAR не содержит объявления модуля, система модулей создает автоматический модуль со следующими свойствами:
- предполагаемое имя (это важный бит здесь)
- читает все остальные модули
- экспортирует все пакеты
Maven опирается на этот механизм, и как только вы создадите module-info.jar
он помещает все зависимости в путь модуля.
Автоматические имена
Есть два способа определить имя автоматического модуля:
- запись в манифесте
- угадать по имени файла JAR
В первом случае имя было специально выбрано сопровождающим, поэтому его можно считать стабильным (например, оно не изменяется при модульности проекта). Второй, очевидно, нестабилен во всей экосистеме - не все настройки проекта приводят к одинаковым именам файлов их зависимостей.
Что это значит?
Причина предупреждений заключается в том, что некоторые из ваших зависимостей являются автоматическими модулями и не определяют их будущее имя модуля в манифесте. Вместо этого их имя происходит от имени файла, что делает их нестабильными
Стабильные имена
Так почему же нестабильные имена являются такой проблемой? Предположим, что ваша библиотека публикуется с requires guava
и мои рамки публикуются с requires com.google.guava
, Теперь кто-то использует вашу библиотеку с моим фреймворком, и вдруг им нужны модули guava и com.google.guava в пути их модулей. У этой проблемы нет безболезненного решения, поэтому ее нужно предотвратить!
Как? Например, отговаривая разработчиков от публикации артефактов, которые зависят от автоматических модулей на основе имени файла.
[ПРЕДУПРЕЖДЕНИЕ] * Обязательные авто-модули на основе имени файла обнаружены. Пожалуйста, не публикуйте этот проект в публичном хранилище артефактов! *
Это потому, что у меня всего несколько модулей с module-info.java, а не весь проект?
Нет, это не из-за нескольких модулей, перечисленных на module-info.java
но генерируется maven-compiler-plugin
для всех автоматических модулей, найденных в графе модулей.
Что это значит?
Не публиковать текущий проект настаивает, вероятно, потому что автоматические модули, как ожидается, будут преобразованы их владельцами в именованные или явные модули, а затем опубликованы в репозитории, что также может привести к изменению их имени модуля. Кроме того, здесь следует обратить внимание на то, что в соответствии с документом о прогрессе Maven ~> Java + 9 + - + Jigsaw, они все еще не полностью готовы к версиям плагинов, совместимых с JDK9.
Просто, чтобы изобразить пример для такого варианта использования. Продумайте эти строки -
- Я опубликовал артефакт
com-foo-bar:1.0.0-SNAPSHOT:jar
, - Еще один мой проект
com-xyz:1.0.0
зависит от этого. - В конце концов ваш проект опирается на
com-foo-bar
транзитивно черезcom-xyz
Вы планируете модулировать свой код и использовать что-то вроде
module your.module { requires com.foo.bar; requires com.xyz; }
(необходимо указать транзитивные зависимости в объявлениях модуля отдельно)
- Все работало нормально, но до того времени я решил модульно оформить свои библиотеки.
- Теперь, первое, что я сделал, это назвал мои модули!
И я сделал что-то фантастическое, чтобы явно назвать мои усилия, как это:-
module modular.com.foo.bar {}
Я заканчиваю тем, что ломаю код любой зависимой библиотеки и, в конечном счете, любой, которая зависит от вашей, модульным способом.
Примечание. Я согласен с тем, что вы не будете использовать SNAPSHOT в производстве, но могут быть случаи, когда в конечном итоге вы полагаетесь на артефакт, который все еще находится в стадии разработки.
Редактировать: из комментариев @khmarbaise
Понятно, что люди хотели бы публиковать в артефактах, но если они не знают о последствиях, вы будете избиты этим в будущем.
Maven хотел бы прояснить, что ПРЕДУПРЕЖДЕНИЕ в этом случае является очень серьезным, что могло бы вместо этого привести к ОТКАЗУ, но с ним было бы плохо работать.
Идеальный способ справиться с этим состоит в том, что владельцы библиотек планируют перенести свои артефакты в JDK9, а дерево обходится снизу вверх, и в этом случае именованный / явный модуль будет единственным преобладающим аспектом без необходимости использования автоматических имен модулей и такие предупреждения.
Я получил это предупреждение, когда в своем файле module-info.java я добавил класс из самого модуля, мне пришлось сделать это для отладки моего тестового файла в NetBeans, но это явно неправильно, так как это не модуль..
module net.my.package.xy
{
requires java.logging;
requires java.naming;
requires javax.jms.api;
//THAT GENERATES THE WARNING:
exports net.my.package.xy.MyClass;
}
С maven-compiler-plugin v3.7.0
это информационное сообщение. Не уверен, почему вы видите это как предупреждение...
Вот что я получаю, когда создаю свой проект на основе Java 10 с module-info.java
:
[INFO] Required filename-based automodules detected. Please don't publish this project to a public artifact repository!