Не удается получить дескриптор модуля для автоматически сгенерированных имен модулей в Java 9?
Мой проект зависит от транспорта Netty Epoll. Вот зависимость:
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-transport-native-epoll</artifactId>
<version>${netty.version}</version>
<classifier>${epoll.os}</classifier>
</dependency>
Автоматически сгенерированное имя модуля для этой зависимости:
netty.transport.native.epoll
И как native
ключевое слово зарезервировано в Java 9 Я не могу добавить этот модуль в качестве зависимости к моему проекту:
module core {
requires netty.transport.native.epoll;
}
Из-за:
module not found: netty.transport.<error>
Дополнительно кувшин --describe-module
сообщает следующее:
Невозможно получить дескриптор модуля для: netty-transport-native-epoll-4.1.17.Final-SNAPSHOT-linux-x86_64.jar netty.transport.native.epoll: Неверное имя модуля: "native" не является идентификатором Java
Есть ли обходные пути? (конечно, кроме "выпустить правильный артефакт нетто").
Как быстрое решение для сопровождающих - вы можете добавить следующую строку для сборки:
<manifestEntries>
<Automatic-Module-Name>netty.transport.epoll</Automatic-Module-Name>
</manifestEntries>
2 ответа
Ну, решение этого, кажется, таково:
переименование самого артефакта(может быть предпочтительным не для всех владельцев)ИЛИ ЖЕ
Другой способ, позволяющий беспрерывно использовать одно и то же имя артефакта с новым (другим) именем модуля, может заключаться в упаковке META-INF/MANIFEST.MF артефакта с атрибутом Automatic-Module-Name, который управляет именем используемого модуля. по дескриптору модуля при преобразовании в автоматический модуль.
ИЛИ ЖЕ
Владелец артефакта может добавлять объявления модулей, используя
module.info.java
в их банку. (это может привести к медленной восходящей миграции)
Поскольку объявление модуля определено в спецификации как:
Объявление модуля представляет имя модуля, которое может использоваться в других объявлениях модуля для выражения отношений между модулями. Имя модуля состоит из одного или нескольких идентификаторов Java (§3.8), разделенных символом "." жетоны.
Перекрестно декларации предполагают -
В некоторых случаях доменное имя в Интернете может быть неправильным именем пакета. Вот некоторые предлагаемые соглашения для решения этих ситуаций:
Если имя домена содержит дефис или любой другой специальный символ, не разрешенный в идентификаторе (§3.8), преобразуйте его в подчеркивание.
Если какой-либо из компонентов имени пакета в результате является ключевым словом (§3.9), добавьте к ним подчеркивание.
Если любой из результирующих компонентов имени пакета начинается с цифры или любого другого символа, который не допускается в качестве начального символа идентификатора, перед компонентом ставится префикс подчеркивания.
Но помните, что Underscore - это ключевое слово в Java9.
int _; // is would throw error on javac based out of JDK9
int _native; // works fine
С этого момента вы также можете использовать этот небольшой плагин Maven для автоматического изменения файла манифеста в банке Scala в локальном репозитории Maven: https://github.com/makingthematrix/scala-suffix
По ссылке вы найдете обзор всей проблемы и то, что вам нужно добавить к вам, но меня также попросили объяснить здесь, так что вот оно:
Как уже упоминалось, Java не распознает суффиксы в именах модулей вроде
_2.13
как номера версий и рассматривать их как неотъемлемую часть имен модулей. Итак, когда ваш проект пытается использовать класс из зависимости Scala, он будет искать
your.scala.dependency.2.13
вместо your.scala.dependency он не сможет этого сделать и выйдет из строя.
Чтобы исправить это на вашей стороне (то есть без каких-либо действий со стороны создателя библиотеки), добавьте это в
<plugins>
раздел вашего
pom.xml
:
<plugin>
<groupId>io.github.makingthematrix</groupId>
<artifactId>scala-suffix-maven-plugin</artifactId>
<version>0.1.0</version>
<configuration>
<libraries>
<param>your-scala-dependency</param>
</libraries>
</configuration>
<executions>
<execution>
<goals>
<goal>suffix</goal>
</goals>
</execution>
</executions>
</plugin>
где
your-scala-dependency
- это имя вашей зависимости Scala без суффикса версии (если их несколько, просто добавьте их с дополнительными
<param>
теги). Это должно быть так же, как
artifactId
в твоей
<dependency>
раздел.
Плагин изменяет файл JAR зависимости в вашем локальном репозитории Maven. Открывает банку, читает
META-INF/MANIFEST.MF
и добавляет к нему строчку:
Automatic-Module-Name: your-scala-dependency
Если свойство
Automatic-Module-Name
уже существует, плагин ничего не делает - мы предполагаем, что в этом случае зависимость уже должна работать. Это предотвращает изменение плагином одного и того же файла JAR более одного раза.