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
Eclipse is confused by imports ("accessible from more than one module")
提问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.awt
or javax.swing
is included in the .jar files.
例如,当javax.awt
或javax.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.8
makes the whole thing work again.
On another machine with Eclipse 2018-09
this 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-09
it works fine. Why?
我在 Eclipse 上2019-03
,在(用于测试目的)新安装的Eclipse 2018-09
它工作正常。为什么?
采纳答案by howlger
This is caused by
这是由
- a JAR on the Classpaththat contains the package
java.awt
that 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.awt
exists in the system module java.desktop
and 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
java
tojava_util
andjavax
tojavax_util
) and recreate the JAR - If you have only the
.class
files you have to decompile the.class
files first
- If you have the source code, change the package names (e.g. change the package and subpackae
- 将编译器合规性设置为 1.8(正如您已经提到的)
- 重新构建JAR以避免JAR中的Java 系统库包名称(如果使用反射,可能需要额外的代码更改):
- 如果你的源代码,更改程序包的名称(如改变包装和subpackae
java
到java_util
和javax
到javax_util
),并重新创建JAR - 如果您只有
.class
文件,则必须先反编译.class
文件
- 如果你的源代码,更改程序包的名称(如改变包装和subpackae
回答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' }