无法为 Java 9 中自动生成的模块名称派生模块描述符?

Unable to derive module descriptor for auto generated module names in 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>

此外,jar 工具 --describe-module 报告如下:

Unable to derive module descriptor for: netty-transport-native-epoll-4.1.17.Final-SNAPSHOT-linux-x86‌_64.jar netty.transport.native.epoll: Invalid module name: 'native' is not a Java identifier

有什么解决方法吗? (当然 "release correct netty artifact" 除外)。

:

作为维护者的快速修复——你可以添加下一行来构建:

<manifestEntries>
   <Automatic-Module-Name>netty.transport.epoll</Automatic-Module-Name>
</manifestEntries>

这个问题的解决方案似乎是:-

  • 一种可以不间断地使用具有新(不同)模块名称的相同工件名称的方法是打包 META-INF/MANIFEST.MF 具有属性 Automatic-Module-Name 的工件,该属性控制模块描述符在转换为自动模块时使用的模块名称。

  • 工件所有者可以使用 module-info.java 添加模块声明到他们的 JAR。 (这可能会导致缓慢的自下而上迁移)

因为 module declaration 在规范中定义为:

A module declaration introduces a module name that can be used in other module declarations to express relationships between modules. A module name consists of one or more Java identifiers (§3.8) separated by "." tokens.


有趣的是 declarations 建议 -

In some cases, the Internet domain name may not be a valid package name. Here are some suggested conventions for dealing with these situations:

  • If the domain name contains a hyphen, or any other special character not allowed in an identifier (§3.8), convert it into an underscore.

  • If any of the resulting package name components are keywords (§3.9), append an underscore to them.

  • If any of the resulting package name components start with a digit, or any other character that is not allowed as an initial character of an identifier, have an underscore prefixed to the component.

但在这样做时请记住 Underscore is a keyword in Java9

int _;  // is would throw an error on javac based out of JDK9
int _native; // works fine

从现在开始,您还可以使用这个小型 Maven 插件自动修改本地 Maven 存储库中 Scala jar 中的清单文件:https://github.com/makingthematrix/scala-suffix

在link下你会找到整个问题的概述以及你需要补充的内容pom.xml,但我被要求在这里也解释一下,所以就这样:

正如已经提到的,Java 不会将 _2.13 等模块名称中的后缀识别为版本号,并将它们视为模块名称的组成部分。因此,当您的项目尝试使用 Scala 依赖项中的 class 时,它会寻找 your.scala.dependency.2.13 而不是 your.scala.dependency,它将失败,并且会崩溃。

要在您这边解决此问题(即无需图书馆创建者采取任何行动)将其添加到 pom.xml:

<plugins> 部分
<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> 标记)。这应该与 <dependency> 部分中的 artifactId 相同。

该插件会修改您本地 Maven 存储库中依赖项的 JAR 文件。它打开罐子,读取 META-INF/MANIFEST.MF 并向其添加一行:

Automatic-Module-Name: your-scala-dependency

如果 属性 Automatic-Module-Name 已经存在,插件什么都不做 - 我们假设在这种情况下依赖应该已经工作。这可以防止插件多次修改同一个 JAR 文件。