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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51094274/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 23:57:06  来源:igfitidea点击:

Eclipse can't find XML related classes after switching build path to JDK 10

javaeclipsemavenjava-10

提问by Carsten

I'm developing on a Maven project(branch platform-bom_brussels-sr7) in Eclipse. When I recently tried switching the Java Build Path for the project to JDK 10, Eclipse build can no longer find classes such as javax.xml.xpath.XPath, org.w3c.dom.Document, or org.xml.sax.SAXException. It seems only XML related classes are impacted, mostly from the Maven dependency xml-apis-1.4.01.

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

Trying a Maven build from Eclipse works without errors. Ctrl-LeftClick on one of the supposedly missing classes finds the class and opens it in the Eclipse editor. It seems only the Eclipse build is impacted.

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

I tried several things, but none helped. I tried:

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

  • Project Clean
  • Different Eclipse Versions: Oxygen and Photon.
  • Running Eclipse itself with JDK 8 and JDK 10.
  • Changing Compiler Compliance level for the project. It builds with compliance level 8 and 10 under JDK 8 build path and fails for both with JDK 10 in build path.
  • 项目清洁
  • 不同的 Eclipse 版本:氧气和光子。
  • 使用 JDK 8 和 JDK 10 运行 Eclipse 本身。
  • 更改项目的编译器合规性级别。它在 JDK 8 构建路径下以合规性级别 8 和 10 构建,并且在构建路径中使用 JDK 10 时都失败。

采纳答案by Stephan Herrmann

I assume that the project being migrated from Java 1.8 still has no module-info.java. This implies you are compiling code in the "unnamed module".

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

Code in the unnamed module "reads" all observable named and unnamed modules, in particular it reads module "java.xml" from the JRE System Library. This module exports package like java.xml.xpath.

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

Additionally, you have xml-apis.javaon the classpath, which contributes another set of packages of the same names (java.xml.xpathand friends). These are said to be associated to the unnamed module, like your own code.

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

This situation violates the requirement of "unique visibility"as defined in JLS §7.4.3(last paragraph). In particular every qualified type name Q.Id (JSL §6.5.5.2) requires that its prefix Q is a uniquely visible package (I'm disregarding the case of nested types for simplicity). Ergo: the program is illegal and must be rejected by compilers.

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

This leaves us with one question and two solutions:

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

(1) Question: Why is javac accepting the program?

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

(2) Solution: If you add module-info.javato your project, you can control via requireswhich module your project reads, either requires java.xml;or requires xml.apis;(where "xml.apis" is the automatic module name of "xml-apis-1.4.01.jar).

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

(3) Solution: Short of turning your project into a module, you can still avoid the conflict by excluding java.xmlfrom the set of observable modules. On the command line this would be done using --limit-modules. The equivalent in Eclipse is the "Modularity Details" dialog, see also the JDT 4.8 New&Noteworthy(look for Contentstab). Since java.xmlis implicitly required via a lot of other default-observable modules, it may be a good idea to push everything except for java.basefrom right ("Explicitly included modules") to left ("Available modules") (and selectively re-add those modules that your project needs).

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

PS: Eclipse still doesn't provide an ideal error message, instead of "cannot be resolved" it should actually say: "The package javax.xml.xpath is accessible from more than one module: javax.xml, <unnamed>.

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

PPS: Also weird: how come that changing the order between JRE and a jar on the classpath (such ordering is not a concept supported by javac nor JEP 261) changes the behavior of the compiler.

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

EDITs:

编辑:

  • Alex Buckley confirmedthat the given situation is illegal, despite what javac says. Bug against javac has been raised as JDK-8215739. This bug has been acknowledged months before the release of Java 12. As of 2019-06 it has been decided that also Java 13 will ship without a fix. Similarly for Java 14. The bug was temporarily scheduled for Java 15, but this plan has been dropped on 2020-04-20.
  • Eclipse error message has been improvedto mention the real problem.
  • In Eclipse 2019-06 the UI used for Solution (3) has been revamped. Up-to-date documentation can be found in the online help.
  • 尽管 javac 怎么说,Alex Buckley确认给定的情况是非法的。针对 javac 的错误已作为JDK-8215739提出。这个错误在 Java 12 发布前几个月就被确认了。截至 2019 年 6 月,已经决定 Java 13 也将在没有修复的情况下发布。Java 14 也是如此。该错误暂时安排在 Java 15 中,但该计划已于 2020 年 4 月 20 日取消。
  • Eclipse 错误消息已得到改进以提及真正的问题。
  • 在 Eclipse 2019-06 中,用于解决方案 (3) 的 UI 已经过改进。可以在在线帮助中找到最新的文档。

回答by gagan singh

jdk 9+ brought in changes related to project jigsaw. JDK was broken down into various modules and some modules, javaee, jaxb and xml related, are no more loaded by default. You should add these to your maven build directly, instead of expecting them to be in jre classpath. see this SO question

jdk 9+ 带来了与项目拼图相关的更改。JDK 被分解成各种模块,一些模块,javaee、jaxb 和 xml 相关,默认情况下不再加载。您应该将这些直接添加到您的 Maven 构建中,而不是期望它们在 jre 类路径中。看到这个问题

回答by Garret Wilson

This seems to have been reported as Eclipse Bug 536928. Maybe if everyone were to go vote on it it would get them to raise the priority.

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

回答by Yossi

This is more of a work-around, but from my experience it can be resolved by going to the "Java Build Path", the "Order and Export" tab, and sending the "Maven Dependencies" to the bottom (so it's below the "JRE System Library").

这更像是一种解决方法,但根据我的经验,可以通过转到“Java 构建路径”、“订单和导出”选项卡,并将“Maven 依赖项”发送到底部(因此它位于“JRE 系统库”)。

回答by df778899

Have seen something very similar under Eclipse 4.8.0 and JDK 10. E.g.

在 Eclipse 4.8.0 和 JDK 10 下看到了非常相似的东西。例如

import org.w3c.dom.Element;

was failing to compile in Eclipse with: The import org.w3c.dom.Element cannot be resolved

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

Even so, pressing F3(Open Declaration) on that import, Eclipse was able to open the interface definition - in this case under xml-apis-1.4.01.jar.

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

Meanwhile, builds from Maven direct were working fine.

同时,从 Maven 直接构建工作正常。

In this case the fix was to remove this dependency from the pom.xml:

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

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

Then the compile errors in Eclipse melted away. Following F3again showed the Elementinterface - now under the java.xmlmodule, under the JRE System Library under the project. Also the Maven build remained fine.

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

This feels like a problem with Eclipse resolving a class that it finds in both a JDK module and dependent .jar file.

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

Interestingly, in a separate environment, this time under Eclipse 4.9.0 and JDK 11, all is fine, with or without the xml-apis:1.4.01dependency.

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

回答by steffen

What happens hereis you have a wildcard import like import org.w3c.dom.*, stating you want to import all classes from package org.w3c.dom. Now, if there's at least one class in org.w3c.domprovided by a second source, Java must not start (as pointed out here).

这里发生的事情是你有一个通配符导入import org.w3c.dom.*,说明你想从包中导入所有类org.w3c.dom。现在,如果有在至少一类org.w3c.dom由第二源提供的Java不能启动(如指出,在这里)。

(By the way, the message "... cannot be resolved" is replaced by a more accurate error message "The package org.w3c.dom is accessible from more than one module: <unnamed>, java.xml" in more recent Eclipse versions, see this merged change requestby Stephan Herrmann.)

(顺便说一句,消息“ ...无法解析”被更准确的错误消息“ The package org.w3c.dom is access from more module: <unnamed>, java.xml”在最近Eclipse 版本,请参阅Stephan Herrmann 的此合并更改请求。)

To resolve this problem

为了解决这个问题

  1. Open the "Open Type" dialog (Ctrl+Shift+T).
  2. Enter the completeimport, so org.w3c.dom.*or org.w3c.dom..
  3. Check the entire list for multiple sources. All entries here should contain only something like "jdk-11-...".
  4. Gather all JARs that contain classes you have multiple sources for.
  5. Open the "Dependency Hirarchy" tab from pom.xml.
  6. Search for the JAR file.
  7. Add an exlusion (right click or edit the pom.xmlmanually).
  1. 打开“打开类型”对话框(Ctrl+ Shift+ T)。
  2. 输入完整的导入,soorg.w3c.dom.*org.w3c.dom..
  3. 检查多个来源的整个列表。此处的所有条目都应仅包含“jdk-11-...”之类的内容。
  4. 收集包含您有多个源的类的所有 JAR。
  5. pom.xml.打开“依赖层次结构”选项卡。
  6. 搜索 JAR 文件。
  7. 添加排除(右键单击或pom.xml手动编辑)。

Example

例子

I had this findbugs dependency in my pom.xml:

我在我的中有这个 findbugs 依赖项pom.xml

<dependency>
    <groupId>com.google.code.findbugs</groupId>
    <artifactId>findbugs</artifactId>
    <version>${findbugs.version}</version>
</dependency>

Findbugs has two dependencies that need to be excluded:

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>

回答by Guillaume

In my case the problem was that xercesImpl : 2.10.0was a (transient) dependency. This jar bundles org.w3c.dom.html.HTMLDOMImplementation.

在我的情况下,问题是xercesImpl : 2.10.0(瞬态)依赖。这个 jar 包org.w3c.dom.html.HTMLDOMImplementation

As far as I understand the org.w3c.dompackage then becomes available from two modules, causing the build to fail. In case one of the dependencies (direct or transient) has classes in one of the 25 packages exported by the java.xml moduleyour build will fail.

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

Excluding xercesImpl (and also the offenders listed below) in Maven solved the issue for me:

在 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>

Thanks to Rune Flobakk for giving the hint here: https://bugs.eclipse.org/bugs/show_bug.cgi?id=536928#c73

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

Other offenders:

其他违法者:

  • batik-ext : 1.9(bundles org.w3c.dom.Window)
  • xom : 1.2.5(bundles org.w3c.dom.UserDataHandler)
  • stax-api : 1.0.2(bundles javax.xml.stream.EventFilter)
  • xml-apis : 1.4.01(bundles org.w3c.dom.Document)
  • 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)