【问题标题】:Unable to derive module descriptor for auto generated module names in Java 9?无法为 Java 9 中自动生成的模块名称派生模块描述符?
【发布时间】:2018-03-12 02:24:47
【问题描述】:

我的项目依赖于 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 报告以下内容:

无法为以下各项派生模块描述符: netty-transport-native-epoll-4.1.17.Final-SNAPSHOT-linux-x86‌_64.jar netty.transport.native.epoll:无效的模块名称:'native' 不是 Java标识符

有什么解决方法吗? (当然,“发布正确的 netty 工件”除外)。

EDIT

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

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

【问题讨论】:

    标签: java netty java-9 java-platform-module-system module-info


    【解决方案1】:

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

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

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

    由于 module declaration 在规范中定义为:

    模块声明引入了一个模块名,可以在 其他模块声明来表达模块之间的关系。 一个 模块名称由一个或多个Java identifiers (§3.8)分隔 经过 ”。”令牌。


    有趣的是declarations 建议-

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

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

    • 如果任何生成的包名称组件是关键字(第 3.9 节), 为它们添加下划线。

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

    但请记住,Underscore is a keyword in Java9

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

    【讨论】:

    • 谢谢哥们。在 netty 构建期间添加了&lt;Automatic-Module-Name&gt;netty.transport.epoll&lt;/Automatic-Module-Name&gt;,它可以工作。
    • 这两种方法都需要修改依赖包(例如问题中的netty)。有没有办法在不修改包的情况下指定模块名称?
    • @Searene 我在 Maven 上阅读并听说过类似 moditect plugin 的内容。但老实说,我还没有尝试过。我真的考虑过联系作者或尝试提交修复作为处理它的最佳方法。当然,它不会立即解决问题,而是避免在使事情适用于特定用例的方向上进行多次迭代。
    • @Searene 我完全同意你的看法。这并不能真正解决问题。像往常一样,当我们开发一个项目时,我很少会自己构建依赖包。所以我不赞成这个答案
    【解决方案2】:

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

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

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

    要在您这边解决此问题(即无需库创建者采取任何行动),请将其添加到您的 pom.xml&lt;plugins&gt; 部分:

    <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 依赖项的名称,不带版本后缀(如果有多个,只需添加更多&lt;param&gt; 标记)。这应该与&lt;dependency&gt; 部分中的artifactId 相同。

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

    Automatic-Module-Name: your-scala-dependency
    

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

    【讨论】:

      猜你喜欢
      • 2019-07-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多