Eclipse被导入所迷惑(“可从多个模块访问”)

Kra*_*ock 3 java eclipse jar

引用简单的.jar文件时,Eclipse会显示错误消息:

可以从多个模块中访问包java.awt:<未命名>,java.desktop

例如,当.jar文件中包含javax.awt或时,就会发生这种情况javax.swing

最简单的示例如下:

package test;

import javax.swing.JDialog;

public class Test {
    public static void main(String[] args) {
        new JDialog();
    }
}
Run Code Online (Sandbox Code Playgroud)

仅使用文件夹结构javax/swing(无需文件)将.jar文件添加到类路径中将导致出现错误。我正在使用JDK 10/12(均无效)。设置编译器遵从性1.8可使整个过程再次运行。在另一台与Eclipse 2018-09此兼容的机器上,编译器遵从性设置为10

我在Eclipse 2019-03上(出于测试目的)在新安装的设备Eclipse 2018-09上工作正常。为什么?

Anu*_*Raj 37

我在 Eclipse 中找到了一个简单的解决方案来解决这个问题。

  1. 在 Eclipse 中点击Ctrl + Shift + T打开Open Type提示符。
  2. 键入导致问题的包的名称。对我来说,这是org.w3c.dom
  3. 搜索结果将显示加载此包的所有位置。
  4. 从结果中出现的类路径中删除除 JDK 11 库之外的所有 JAR。

我的项目是一个遗留项目,我必须从构建路径中删除很多 JAR。另外,我的项目没有使用Maven。因此删除 JAR 是一个相当简单的步骤。对于其他构建工具(如 ANT、Maven、Gradle 等),这些步骤可能会有所不同。我刚刚解释了上面的故障排除步骤。

  • Ctrl + Shift + T - 效果很好。我可以看到 JRE 和 m2 存储库中都有一个 jar。 (4认同)
  • Ctrl + Shift + T 是救星!每个人都解释了问题,但没有人解释如何找到有问题的依赖关系。 (4认同)
  • 这比评分较高的答案更有帮助。 (4认同)

K. *_*lor 14

因为我敢打赌,很多人会在使用模块化 Java 时遇到这个问题,所以我会提供帮助并给出真正的答案。当您的项目中包含使用包的代码的依赖项时,会发生此错误,这些包也在您的项目引用的模块中。如果您的项目已将源代码兼容性设置为 Java 12 之类的内容,它将开始强制执行该规则,该规则在 Java 中一直存在。“不要在你自己的代码中使用属于 JDK 的包。” 不幸的是,多年来,许多开发人员和供应商都这样做了。不能再那样做了。如果您将项目设置为 Java 12 源代码兼容性,Eclipse 会添加 JDK 模块,其中包括“java. ”和“javax. ”甚至“jdk. ”、“org.w3c.”。"。这些包可能正在被您的依赖项或其传递依赖项使用。

如何修复:您需要查看它抱怨的是哪个包,并在包资源管理器中展开“项目和外部依赖项”节点。找出哪个依赖项正在使用该包。然后您可以简单地从您的项目中排除该依赖项。或者您可以获取该依赖项的来源(如果可用),并使用更改的包重建 jar。否则,您必须删除该依赖项并找到该技术的替代品。痛吧?

如果它是一个传递依赖,你通常可以将它排除在外。这是基于 Gradle 的项目的示例。

configurations {
    all*.exclude group: 'xml-apis'
}
Run Code Online (Sandbox Code Playgroud)

  • 这是正确的。例如,Java“拥有”包“java”,因此不允许使用“java.anything”。对于“sun.anything”、“javax.anything”也是如此。 (5认同)

JZa*_*ela 14

就我而言,这是因为我在 POM.xml 文件中包含了一个依赖项 (Apache Tika)。

我不得不强制排除包含在该依赖项中导入时出现错误的类的模块:

    <dependency>
        <groupId>org.apache.tika</groupId>
        <artifactId>tika-parsers</artifactId>
        <version>1.24.1</version>
        <exclusions>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
Run Code Online (Sandbox Code Playgroud)

它以这种方式对我有用。


zak*_*mck 13

我认为我对这个问题的看法可能有用。

javax.xml.stream对于依赖于xml-apisstax-api、 或 等工件的旧 Maven 项目,我在 , 下的类中遇到了此错误geronimo-stax-api

从技术上讲,问题是其他人已经说过的:这些工件javax.xml.*在不了解 Java 模块的情况下公开了包(它们是后来发明的),因此包被自动分配给未命名的模块,这与包含在 Java 模块中的相同包发生冲突。 JDK的最新版本中,包有自己的模块名称,因此同一个包会产生两个不同的模块,这是被禁止的。

也就是说,实际的解决方案本质上是使用Maven 排除来从项目中删除这些依赖项,并让它使用 JDK 版本(或者,当然,如果是您的情况,则将它们作为直接依赖项删除)。如果您正在使用另一个构建系统,请使用等效的方法。

从理论上讲,JDK 提供的这些包的最新版本可能不向后兼容,实际上,我怀疑此类 JSR 规范多年来发生了很大变化,到目前为止,我还没有看到它们的替换有任何问题。

  • 对冲突部门列表非常有帮助。谢谢。 (3认同)

MSi*_*nce 12

另请参阅:org.w3c.dom 包可以从多个模块访问:<unnamed>、java.xml,我在其中回答:

令人失望的是,我没有看到任何编译器标志来显示问题出在哪个 jar 即使 -Xlint:module 似乎也没有显示任何有用的东西,并且 eclipse 也没有揭示这个问题

为了找到 java.awt 的来源,我一直在使用这个脚本:

mvn dependency:copy-dependencies -DincludeScope=test -DoutputDirectory=deps
for i in deps/*.jar; do if unzip -l $i| grep -q java.awt; then echo $i; fi ; done
Run Code Online (Sandbox Code Playgroud)

严格来说,您不必指定范围测试,因为这是默认设置,但我已将其包含compile在内,因为您可能想使用它


how*_*ger 8

这是由于

  • 对JAR 类路径包含 java.awt 也存在于系统库,但
  • JRE系统库ModulePath进行

Java平台模块系统(JPMS)中,不允许在多个模块中使用同一软件包。如果ModulePath进行类路径时,对一切类路径被作为处理<unnamed>模块(在你的情况下,包装java.awt系统模块中不存在java.desktop,也通过在该JAR 类路径模块中<unnamed>)。

由于无法将JRE系统库Modulepath移到Classpath有关详细信息,请参见Stephan Herrmann的此答案),因此您只有以下选项:

  • 将编译器合规性设置为1.8(如前所述)
  • 重建JAR避免JAR内的Java系统库软件包名称(如果使用反射,则可能需要更改其他代码):
    • 如果您有源代码,请更改包名称(例如,将包和子包更改javajava_utiljavaxjavax_util然后重新创建JAR)
    • 如果只有.class文件,则必须先反编译.class文件

  • @howlger 感谢您的链接。不幸的是,添加 module-info.java 并不是一个实用的解决方案,因为一旦执行此操作,您就需要项目的所有依赖项都是模块,或者至少具有自动模块名称。我的许多依赖项没有“Automatic-Module-Name”标头,因此我必须使用文件名。因此 `com.google.guava_21.0.0.jar` 变成了 `requires com.google.guava.21.0.0` 但这是模块信息中的语法错误!抓住22... (2认同)

lor*_*s91 7

我发现 Java 11 和 xmlbeans 库有一些有趣的行为。xmlbeans 库是Apache POI的传递依赖项,Apache POI 是一个非常流行的处理 Microsoft Office 文档的库,它用于处理较新 Office 格式的内部 XML 结构。我已经使用Apache POI 3.9对其进行了测试,尽管 Eclipse 显示了错误,但它工作得非常好。所以,我猜想在 Java 11 中这条规则并没有完全执行。

  • 更新到 Apache POI 5.0.0 时遇到完全相同的问题,添加 `&lt;exclusions&gt;&lt;exclusion&gt;&lt;groupId&gt;xml-apis&lt;/groupId&gt;&lt;artifactId&gt;xml-&lt;/artifactId&gt;&lt;/exclusion&gt;&lt; /exclusions&gt;` 到 poi-ooxml 依赖项就成功了 (4认同)