Car*_*ten 29 java eclipse maven java-10
我正在开发Eclipse中的Maven项目(branch platform-bom_brussels-sr7).当我最近尝试切换Java构建路径,为项目JDK 10,Eclipse构建再也找不到类,如javax.xml.xpath.XPath
,org.w3c.dom.Document
或org.xml.sax.SAXException
.似乎只有XML相关的类受到影响,主要来自Maven依赖xml-apis-1.4.01
.
从Eclipse中尝试Maven构建工作没有错误.Ctrl-LeftClick上一个假定缺失的类找到该类并在Eclipse编辑器中打开它.似乎只有Eclipse构建受到影响.
我尝试了几件事,但都没有帮助.我试过了:
Ste*_*ann 33
我认为从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是唯一可见的包(为简单起见,我不考虑嵌套类型的情况)。Ergo:该程序是非法的,必须被编译器拒绝。
这给我们留下了一个问题和两个解决方案:
(1)问题:javac为什么接受该程序?
(2)解决方案:如果您添加module-info.java
到您的项目,你可以控制通过需要哪些模块项目读取,无论是requires java.xml;
或requires xml.apis;
(其中“xml.apis”是“XML的API-1.4.01.jar自动模块名称)。
(3)解决方案:除了将您的项目变成一个模块之外,您仍然可以通过java.xml
从可观察模块中排除来避免冲突。在命令行上,可以使用--limit-modules
。Eclipse中的等效项是“模块化详细信息”对话框,另请参见JDT 4.8 New&Noteworthy(查找“ 目录”选项卡)。由于java.xml
许多其他默认可观察的模块都隐式需要此模块,因此最好将除java.base
右方(“显式包含的模块”)之外的所有内容推至左侧(“可用模块”)(并有选择地重新添加这些模块)您的项目需要的)。
PS:Eclipse仍然没有提供理想的错误消息,而不是“无法解决”,它实际上应该说:“可以从多个模块访问javax.xml.xpath包:javax.xml,<未命名>。
PPS:也很奇怪:改变JRE和类路径上的jar之间的顺序(这种顺序不是javac或JEP 261不支持的概念)会改变编译器的行为。
编辑:
Ste*_*ann 14
虽然(我自己)接受的答案仍然是正确的,但这个故事的进一步转折最近引起了我的注意:
初衷可能是为了实际支持当前的情况。
请参阅原始设计文档“模块系统的状态”(SotMS)中的这段引用:
如果在命名模块和未命名模块中都定义了包,则未命名模块中的包将被忽略。
该文档的日期为 2016/3/8 08:18,并且当时已被标记为“此文档稍微过时”。此外,它对任何实施都不具有法律约束力。该文档仍然具有一定的相关性,因为上面引用的内容正是似乎要实现的内容(并且在JDK-8215739提交javac
多年后仍然实现)。
IOW,冲突并不是第一个和第二个实现之间的冲突,而是 Oracle 内部的冲突,看起来如此。2 票支持这种情况(SotMS 和 javac),只有一票反对(JLS)。
由于 Eclipse 提交者不愿意在 Oracle 中解决此冲突,因此最近的 2022-12 版本的 Eclipse 有一个新的编译器选项:通过将以下行添加到项目的.settings/org.eclipse.jdt.core.prefs
,用户可以选择在这方面忽略 JLS:
org.eclipse.jdt.core.compiler.ignoreUnnamedModuleForSplitPackage=enabled
Run Code Online (Sandbox Code Playgroud)
此选项将决定权交到用户手中:他们想要 JLS 语义还是 SotMS/javac 语义(在本特定问题中)?尽管如此,我们还没有准备好为其提供 UI 选项,以避免用户在没有此处提供的背景信息的情况下轻率地做出此选择。
就我个人而言,我对这种情况并不是特别满意,因为它加剧了 Java 不是一种语言,而是多种语言这一事实。
在我的情况下,问题是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>
Run Code Online (Sandbox Code Playgroud)
感谢 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)这里发生的情况是您有一个通配符导入import org.w3c.dom.*
,表示您要从包中导入所有类org.w3c.dom
。现在,如果至少有一个类由org.w3c.dom
第二个源提供,则 Java 不得启动(如此处指出的)。
(顺便说一句,消息“ ...无法解析”被替换为更准确的错误消息“ The package org.w3c.dom isaccessible from multiple module: <unnamed>, java.xml ”在最近的版本中Eclipse 版本,请参阅 Stephan Herrmann 的合并更改请求。)
为了解决这个问题
org.w3c.dom.*
或org.w3c.dom.
。pom.xml
。pom.xml
手动编辑)。例子
我的 中有这个 findbugs 依赖项pom.xml
:
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>findbugs</artifactId>
<version>${findbugs.version}</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)
Findbugs 有两个需要排除的依赖项:
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>findbugs</artifactId>
<version>${findbugs.version}</version>
<exclusion>
<groupId>xml-apis</groupId>
<artifactId>xml-apis</artifactId>
</exclusion>
<exclusion>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
</exclusion>
</dependency>
Run Code Online (Sandbox Code Playgroud)
虽然 Stephan Herrmann 的答案是正确的,但如果可以帮助其他人,我将发布我的错误以及我如何解决它。我遇到了错误The package javax.xml.namespace is accessible from more than one module: <unnamed>, java.xml
,在检查了有错误的类之后,发现是javax.xml.namespace.QName
导入在抱怨。通过“Open Type”对话框,我发现它是stax-api
通过 eureka 客户端拉取的。这为我解决了这个问题:
<exclusion>
<groupId>stax</groupId>
<artifactId>stax-api</artifactId>
</exclusion>
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
12114 次 |
最近记录: |