Java Eclipse 被导入混淆(“可从多个模块访问”)

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/55571046/
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-11 01:12:50  来源:igfitidea点击:

Eclipse is confused by imports ("accessible from more than one module")

javaeclipsejar

提问by Krann Sock

When referencing simple .jar files, Eclipse shows an error stating:

引用简单的 .jar 文件时,Eclipse 会显示一条错误消息:

The package java.awt is accessible from more than one module: <unnamed>, java.desktop

包 java.awt 可以从多个模块访问:<unnamed>、java.desktop

This happens for instance when javax.awtor javax.swingis included in the .jar files.

例如,当javax.awtjavax.swing包含在 .jar 文件中时就会发生这种情况。

The simplest example would be the following:

最简单的例子如下:

package test;

import javax.swing.JDialog;

public class Test {
    public static void main(String[] args) {
        new JDialog();
    }
}

Adding a .jar file to the classpath with only the folder structure javax/swing(no files needed) will cause the error to appear. I'm using JDK 10/12 (neither works). Setting the compiler compliance to 1.8makes the whole thing work again. On another machine with Eclipse 2018-09this works with compiler compliance set to 10.

将 .jar 文件添加到只有文件夹结构javax/swing(不需要文件)的类路径将导致出现错误。我正在使用 JDK 10/12(都不起作用)。将编译器合规性设置为1.8使整个过程再次运行。在另一台具有Eclipse 2018-09此功能的机器上,编译器合规性设置为10.

I'm on Eclipse 2019-03, on a (for testing purposes) freshly installed Eclipse 2018-09it works fine. Why?

我在 Eclipse 上2019-03,在(用于测试目的)新安装的Eclipse 2018-09它工作正常。为什么?

采纳答案by howlger

This is caused by

这是

  • a JAR on the Classpaththat contains the packagejava.awtthat also exists in the system librarybut the
  • JRE System Libraryis on the Modulepath
  • 对JAR类路径包含java.awt也存在于系统库,但
  • JRE系统库ModulePath进行

In the Java Platform Module System (JPMS)it is not allowed to use the same package in more than one module. If the Modulepathand the Classpathis used, everything on the Classpathis handled as the <unnamed>module (in your case the package java.awtexists in the system module java.desktopand also via the JAR on the Classpathin the module <unnamed>).

Java 平台模块系统 (JPMS) 中,不允许在多个模块中使用相同的包。如果ModulePath进行类路径时,对一切类路径被作为处理<unnamed>模块(在你的情况下,包装java.awt系统模块中不存在java.desktop,也通过在该JAR类路径模块中<unnamed>)。

Since the JRE System Librarycannot be moved from the Modulepathto the Classpath(see this answer by Stephan Herrmann for details), you only have the following options:

由于JRE 系统库无法从Modulepath移动到Classpath有关详细信息,请参阅Stephan Herrmann 的这个答案),您只有以下选项:

  • Set the compiler compliance to 1.8 (as you already mentioned)
  • Rebuilt the JARto avoid Java system library package names inside the JAR(if reflection is used, additional code changes may be necessary):
    • If you have the source code, change the package names (e.g. change the package and subpackae javato java_utiland javaxto javax_util) and recreate the JAR
    • If you have only the .classfiles you have to decompile the .classfiles first
  • 将编译器合规性设置为 1.8(正如您已经提到的)
  • 重新构建JAR避免JAR中的Java 系统库包名称(如果使用反射,可能需要额外的代码更改):
    • 如果你的源代码,更改程序包的名称(如改变包装和subpackaejavajava_utiljavaxjavax_util),并重新创建JAR
    • 如果您只有.class文件,则必须先反编译.class文件

回答by K. Taylor

Since I'll bet lots of people will be running into this problem with modular Java, I'll help and give the real answer. This error happens when you have a dependency in your project that contains code using packages that are also in the modules being referenced by your project. If your project has set the source compatibility to something like Java 12, it will start enforcing the rule, that has been there all along in Java. "Don't use packages that belong to the JDK in your own code." Unfortunately, lots of developers and vendors have done that over the years. Can't do that anymore. If you set your project to Java 12 source compatibility, Eclipse adds the JDK modules which include everything "java." and "javax." and even "jdk.", "org.w3c.". These packages may be in use by your dependencies or their transitive dependencies.

因为我敢打赌,很多人会在使用模块化 Java 时遇到这个问题,所以我会提供帮助并给出真正的答案。当您的项目中包含使用包的代码的依赖项时,会发生此错误,这些包也在您的项目引用的模块中。如果您的项目已将源代码兼容性设置为 Java 12 之类的内容,它将开始强制执行该规则,该规则在 Java 中一直存在。“不要在自己的代码中使用属于 JDK 的包。” 不幸的是,多年来,许多开发人员和供应商都这样做了。不能再那样做了。如果您将项目设置为 Java 12 源代码兼容性,Eclipse 会添加 JDK 模块,其中包括“java. ”和“javax.”甚至“jdk. ”、“org.w3c.”。"。这些包可能正在被您的依赖项或其传递依赖项使用。

How to fix: You need to look at which package its complaining about and expand the "Projects and External Dependencies" node in the Package Explorer. Find out which dependency is using that package. Then you can simply exclude that dependency from your project. Or you could get the source of that dependency, if available, and rebuild the jar with changed packages. Otherwise you have to remove that dependency and find a replacement for that technology. Pain huh?

如何修复:您需要查看它抱怨的是哪个包,并在包资源管理器中展开“项目和外部依赖项”节点。找出哪个依赖项正在使用该包。然后您可以简单地从您的项目中排除该依赖项。或者您可以获取该依赖项的来源(如果可用),并使用更改的包重建 jar。否则,您必须删除该依赖项并找到该技术的替代品。痛吧?

If its a transitive dependency you can often just exclude it. Here is an example of that for Gradle based projects.

如果它是一个传递依赖,你通常可以排除它。这是基于 Gradle 的项目的示例。

configurations { all*.exclude group: 'xml-apis' }

配置 { all*.exclude 组:'xml-apis' }