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

Другие вопросы по тегам