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

我的项目依赖于Netty Epoll transport。以下是依赖关系:

<dependency>
    <groupId>io.netty</groupId>
    <artifactId>netty-transport-native-epoll</artifactId>
    <version>${netty.version}</version>
    <classifier>${epoll.os}</classifier>
</dependency>

此依赖项自动生成的模块名称为:

netty.transport.native.epoll

由于关键字在Java 9中保留,因此我无法将此模块作为依赖项添加到我的项目中:native

module core {
    requires netty.transport.native.epoll;
}

由于:

module not found: netty.transport.<error>

此外,jar 工具还会报告以下内容:--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>

答案 1

解决这个问题的办法似乎是:

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

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

由于模块声明在规范中定义为:

模块声明引入了一个模块名称,该模块名称可以在其他模块声明中用于表示模块之间的关系。模块名称由一个或多个 Java 标识符 (§3.8) 组成,这些标识符由 “.” 标记分隔。


这些声明断断续续地表明——

在某些情况下,互联网域名可能不是有效的软件包名称。以下是处理这些情况的一些建议约定:

  • 如果域名包含连字符或标识符中不允许的任何其他特殊字符 (§3.8),请将其转换为下划线。

  • 如果生成的任何包名称组件是关键字 (§3.9),请向它们附加下划线。

  • 如果生成的任何包名称组件以数字开头,或者不允许作为标识符初始字符的任何其他字符,则组件前面带有下划线。

但请记住,下划线是Java9中的关键字。

enter image description here

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

答案 2

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

在链接下,您将找到整个问题的概述以及您需要添加的内容,但是我被要求也在这里解释,所以这里是:pom.xml

如前所述,Java不会将模块名称中的后缀识别为版本号,并将它们视为模块名称的组成部分。因此,当你的项目尝试使用Scala依赖项中的类时,它将寻找而不仅仅是你的.scala.依赖项,它将无法做到这一点,并且会崩溃。_2.13your.scala.dependency.2.13

要解决此问题(即无需库创建者的任何操作),请将其添加到您的部分:<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>

其中 是没有版本后缀的 Scala 依赖项的名称(如果有多个版本后缀,只需添加具有更多标记的它们)。这应该与您所在部分中的内容相同。your-scala-dependency<param>artifactId<dependency>

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

Automatic-Module-Name: your-scala-dependency

如果该属性已经存在,则插件不执行任何操作 - 我们假设在这种情况下,依赖项应该已经工作。这可以防止插件多次修改同一 JAR 文件。Automatic-Module-Name


推荐