【问题标题】:Muting Java 9 split package errors on IntelliJ在 IntelliJ 上消除 Java 9 拆分包错误
【发布时间】:2024-05-03 19:05:02
【问题描述】:

我有一个 JDK 9 项目。运行mvn install 时,一切正常。将 IntelliJ 2017.2.6 与 JDK 9.0.4 一起使用时,我出现了 由于拆分包而导致数十个编译错误。例如,在我的 POM 中,我设置了对 org.apache.solr:solr-core:7.2.1 的依赖。 IntelliJ 显示的错误之一是:

Error:java: module solr.core reads package org.apache.lucene.search from both lucene.misc and lucene.sandbox

IntelliJ 发出编译错误的原因是:

  1. solr-core 对工件 lucene-misclucene-sandbox 具有 Maven 依赖关系
  2. lucene-misc.jarlucene-sandbox.jar 都在包org.apache.lucene.search 中定义类
  3. IntelliJ 认为lucene-misc.jarlucene-sandbox.jar 是JDK 9 模块(事实上,它们不是模块,它们没有module-info.java 文件)。由于两个 JDK 9 模块不能参与同一个包,IntelliJ 会发出编译错误。

相比之下,Maven 编译器插件没有错误,因为它认为lucene-misc.jarlucene-sandbox.jar 属于 类路径,而不是模块路径。

我显然不想重新打包 Lucene 的东西。

所以我的问题归结为以下几点:如何使 IntelliJ 错误 Error:java: module Mod1 reads package P from both Mod2 and Mod3 静音?

【问题讨论】:

  • 删除你的module-info.java
  • 您的直接依赖项必须进入模块路径,但传递依赖项可以进入任一路径。 Maven 将它们放在类路径上(拆分包无关紧要),而 IntelliJ 将它们放在模块路径上(导致您观察到的问题)。我不知道如何告诉 IntelliJ 在哪里放置传递依赖项。诉诸非模块化项目可能是您唯一的选择。
  • 感谢@ZhekaKozlov 和 Nicolai。希望 JetBrains 的人能够在 IntelliJ 的下一个版本中使这种行为可配置。
  • 我现在看到一个案例,IntelliJ 似乎错误地将某些东西标记为拆分包,而实际上没有。案例很简单,所以我认为这可能是一个错误。我正在等待回复,但详细信息在这里:intellij-support.jetbrains.com/hc/en-us/community/posts/…

标签: intellij-idea module compiler-errors java-9


【解决方案1】:

[短]

如果您想从模块代码运行您的应用程序,这是不可能的。您必须将依赖于碰撞 JAR 的代码迁移到 非模块化e 代码,并将碰撞 jar 添加到类路径中。 (根据 cmets 的建议)

[长]

Intellij 在后台尝试运行 JVM,因此 Intellij 只有在 JVM 可以做到这一点。

当您从模块 jar 运行应用程序时,这意味着您从命名模块运行应用程序。该模块必须要求其所有依赖项,这些依赖项应该是名称模块。请注意,即使是从您的非模块 JAR 创建的 自动模块 也确实被命名。 Java 9 不允许 split-packages 出于可靠配置的原因,只有 未命名的模块 除外。

让它工作的唯一方法是将你的碰撞罐移动到未命名的模块,但是named module cannot depend on unnamed module

实际上,命名模块甚至不能声明对未命名模块的依赖。这种限制是有意的,因为允许命名模块依赖于类路径的任意内容会使可靠的配置变得不可能。

因此,如果您不想重新打包碰撞 jar,则必须将需要碰撞的模块 jars 移动到非模块 jar。

你的 maven 插件用它完成了,因为正如@Nicolai 所说:

Maven 将它们放在类路径上(拆分包无关紧要),而 IntelliJ 将它们放在模块路径上(导致您观察到的问题)。

另请参阅this answer,了解从非模块代码运行应用程序。

【讨论】:

  • 非常感谢@Andrew。