我假设从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)解决方案:如果您添加到项目中,则可以通过要求来控制项目读取的模块,或者(其中“xml.apis”是“xml-apis-1.4.01.jar的自动模块名称)。module-info.java
requires java.xml;
requires xml.apis;
(3)解决方案:除了将项目转换为模块之外,您仍然可以通过从可观察模块集中排除来避免冲突。在命令行上,这将使用 来完成。Eclipse 中的等效项是“Modularity Details”对话框,另请参阅 JDT 4.8 New&Noteworthy(查找“内容”选项卡)。由于通过许多其他默认可观察模块隐式需要,因此最好将除右侧(“显式包含的模块”)之外的所有内容(“可用模块”)推送到左侧(“可用模块”)(并有选择地重新添加项目所需的模块)。java.xml
--limit-modules
java.xml
java.base
PS:Eclipse仍然没有提供理想的错误消息,而不是“无法解析”,它实际上应该说:“包javax.xml.xpath可以从多个模块访问:javax.xml,<未命名>。
PPS:同样奇怪的是:为什么改变JRE和类路径上的jar之间的顺序(这种排序不是javac和JEP 261支持的概念)会改变编译器的行为。
编辑:
- 亚历克斯·巴克利(Alex Buckley)证实,尽管javac说了什么,但给定的情况是非法的。针对javac的错误已被提出为JDK-8215739。这个错误在Java 12发布前几个月就已经被承认了。截至2019-06年,已经决定Java 13也将在没有修复的情况下发布。Java 14也是如此。该错误暂时安排在Java 15上,但此计划已于2020-04-20删除。
- Eclipse 错误消息已得到改进,可以提及真正的问题。
- 在 Eclipse 2019-06 中,用于解决方案 (3) 的 UI 已得到改进。可在联机帮助中找到最新文档。