将构建路径切换到 JDK 10 后,Eclipse 找不到 XML 相关类

新手上路,请多包涵

我正在 Eclipse 中开发 Maven 项目(分支平台-bom_brussels-sr7)。当我最近尝试将项目的 Java 构建路径切换到 JDK 10 时,Eclipse 构建无法再找到诸如 javax.xml.xpath.XPathorg.w3c.dom.Documentorg.xml.sax.SAXException -ce-d16 之类的类似乎只有 XML 相关类受到影响,主要来自 Maven 依赖 xml-apis-1.4.01

尝试从 Eclipse 构建 Maven 没有错误。按住 Ctrl-左键单击其中一个假定缺失的类可找到该类并在 Eclipse 编辑器中将其打开。似乎只有 Eclipse 构建受到影响。

我尝试了几件事,但没有帮助。我试过了:

  • 项目清洁
  • 不同的 Eclipse 版本:氧气和光子。
  • 使用 JDK 8 和 JDK 10 运行 Eclipse 本身。
  • 更改项目的编译器合规性级别。它在 JDK 8 构建路径下以合规性级别 8 和 10 构建,并且在构建路径中使用 JDK 10 时均失败。

原文由 Carsten 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 467
2 个回答

我假设从 Java 1.8 迁移的项目仍然没有 module-info.java 。这意味着您正在“未命名模块”中编译代码。

未命名模块中的代码“读取”所有可观察的命名和未命名模块,特别是它从 JRE 系统库中读取模块“java.xml”。该模块导出类似 java.xml.xpath 的包。

此外,您在类路径上有 xml-apis.java ,它提供了另一组同名的包( java.xml.xpath 和朋友)。据说这些与未命名模块相关联,就像您自己的代码一样。

这种情况违反了 JLS §7.4.3 (最后一段)中定义 的“唯一可见性”的要求。特别是每个限定类型名称 Q.Id ( JSL §6.5.5.2 ) 都要求其前缀 Q 是唯一可见的包(为简单起见,我忽略了嵌套类型的情况)。因此:该程序是非法的,必须被编译器拒绝。

这给我们留下了一个问题和两个解决方案:

(1) 问题:为什么javac接受程序?

(2) 解决方案:如果将 module-info.java 添加到项目中,则可以通过 要求 项目读取哪个模块来控制 requires java.xml;requires xml.apis; .apis”是“xml-apis-1.4.01.jar”的自动模块名称。

(3) 解决方案:除了将您的项目转换为模块之外,您仍然可以通过从可观察模块集中排除 java.xml 来避免冲突。在命令行上,这将使用 --limit-modules 完成。 Eclipse 中的等效项是 “Modularity Details”对话框,另请参阅 JDT 4.8 New&Noteworthy (查找 Contents 选项卡)。由于 java.xml 是通过许多其他默认可观察模块隐式需要的,因此将除了 java.base 之外的所有内容从右(“显式包含的模块”)推到左可能是个好主意(“可用模块”)(并有选择地重新添加项目需要的那些模块)。

PS:Eclipse 仍然没有提供理想的错误消息,而不是“无法解决”,它实际上应该说:“包 javax.xml.xpath 可以从多个模块访问:javax.xml,<未命名>。

PPS:也很奇怪:为什么改变 JRE 和类路径上的 jar 之间的顺序(这种顺序不是 javac 或 JEP 261 支持的概念)会改变编译器的行为。

编辑:

  • 亚历克斯巴克利 确认 给定的情况是非法的,尽管 javac 说了什么。针对 javac 的错误已作为 JDK-8215739 提出。此错误已在 Java 12 发布前几个月得到确认。截至 2019 年 6 月,已决定 Java 13 也将在没有修复的情况下发布。 Java 14 也是如此。这个 bug 被临时安排在 Java 15 上,但是这个计划在 2020-04-20 已经被取消了。
  • Eclipse 错误消息 已得到改进 以提及真正的问题。
  • 在 Eclipse 2019-06 中,用于解决方案 (3) 的 UI 已经过 改进。可以在 联机帮助 中找到最新的文档。

原文由 Stephan Herrmann 发布,翻译遵循 CC BY-SA 4.0 许可协议

在我的例子中,问题是 xercesImpl : 2.10.0 是一个(暂时的)依赖。这个 jar 包 org.w3c.dom.html.HTMLDOMImplementation

据我了解 org.w3c.dom 包然后从两个模块中可用,导致构建失败。如果其中一个依赖项(直接或瞬态)在 java.xml 模块 导出的 25 个包之一中有类,您的构建将失败。

在 Maven 中排除 xercesImpl(以及下面列出的违规者)为我解决了这个问题:

     <dependency>
        <groupId>xyz</groupId>
        <artifactId>xyz</artifactId>
        <version>1.0</version>
        <exclusions>
            <exclusion>
                <groupId>xerces</groupId>
                <artifactId>xercesImpl</artifactId>
            </exclusion>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
            <exclusion>
                ...
            </exclusion>
        </exclusions>
    </dependency>

感谢 Rune Flobakk 在这里给出提示: https ://bugs.eclipse.org/bugs/show_bug.cgi?id=536928#c73

其他违法者:

  • batik-ext : 1.9 (捆绑 org.w3c.dom.Window)
  • xom : 1.2.5 (捆绑 org.w3c.dom.UserDataHandler)
  • stax-api : 1.0.2 (捆绑javax.xml.stream.EventFilter)
  • xml-apis : 1.4.01 (捆绑org.w3c.dom.Document)
  • xml-beans : 2.3.0 (捆绑 org.w3c.dom.TypeInfo)

原文由 Guillaume 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题