在将构建路径切换到JDK 10之后,Eclipse无法找到与XML相关的类

问题描述 投票:21回答:5

我正在开发Eclipse中的Maven project(branch platform-b​​om_brussels-sr7)。当我最近尝试将项目的Java Build Path切换到JDK 10时,Eclipse构建不再能够找到诸如javax.xml.xpath.XPathorg.w3c.dom.Documentorg.xml.sax.SAXException之类的类。似乎只有XML相关的类受到影响,主要来自Maven依赖xml-apis-1.4.01

从Eclipse中尝试Maven构建工作没有错误。 Ctrl-LeftClick上一个假定缺失的类找到该类并在Eclipse编辑器中打开它。似乎只有Eclipse构建受到影响。

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

  • 项目清洁
  • 不同的Eclipse版本:氧气和光子。
  • 使用JDK 8和JDK 10运行Eclipse本身。
  • 更改项目的编译器合规性级别。它在JDK 8构建路径下以符合级别8和10构建,并且在构建路径中使用JDK 10都失败。
java eclipse maven java-10
5个回答
21
投票

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

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

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

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

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

(1)问题:为什么javac接受该计划?

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

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

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

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

编辑:

  • 亚历克斯巴克利confirmed,尽管javac说,给定的情况是非法的。针对javac的bug已被提升为JDK-8215739。这个错误已经在Java 12发布前几个月得到承认。截至2019-06,已经确定Java 13也将在没有修复的情况下发布。
  • Eclipse错误消息has been improved提到真正的问题。
  • 在Eclipse 2019-06中,用于Solution(3)的UI是revamped。可以在online help找到最新的文档。

5
投票

这似乎被报道为Eclipse Bug 536928。也许如果每个人都去投票,它会让他们提高优先级。


2
投票

在Eclipse 4.8.0和JDK 10下看到过非常类似的东西。

import org.w3c.dom.Element;

无法在Eclipse中编译:The import org.w3c.dom.Element cannot be resolved

即便如此,在该导入上按下F3(Open Declaration),Eclipse也能够打开接口定义 - 在本例中是xml-apis-1.4.01.jar

同时,Maven direct的构建工作正常。

在这种情况下,修复是从pom.xml中删除此依赖项:

    <dependency>
        <groupId>xml-apis</groupId>
        <artifactId>xml-apis</artifactId>
        <version>1.4.01</version>
    </dependency>

然后Eclipse中的编译错误消失了。继F3之后再次展示了Element界面 - 现在在java.xml模块下,在该项目下的JRE系统库下。 Maven的构建也很好。

这感觉就像Eclipse解析它在JDK模块和依赖的.jar文件中找到的类一样。

有趣的是,在单独的环境中,这次是在Eclipse 4.9.0和JDK 11下,一切都很好,有或没有xml-apis:1.4.01依赖。


0
投票

jdk 9+带来了与项目拼图有关的变化。 JDK被分解为各种模块,并且默认情况下不再加载一些与javaee,jaxb和xml相关的模块。您应该直接将这些添加到您的maven构建中,而不是期望它们位于jre类路径中。看到这个SO question


0
投票

这更像是一种解决方法,但根据我的经验,可以通过转到“Java Build Path”,“Order and Export”选项卡,并将“Maven Dependencies”发送到底部(因此它位于“JRE系统库”)。

© www.soinside.com 2019 - 2024. All rights reserved.