ECLIPSE被导入搞糊涂了(“可从多个模块访问”)

ryoqjall  于 2022-09-21  发布在  Eclipse
关注(0)|答案(4)|浏览(226)

当引用简单的.jar文件时,Eclipse显示一个错误,声明:
可以从多个模块访问包java.awt:

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

最简单的例子如下:

package test;

import javax.swing.JDialog;

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

将.jar文件添加到仅包含文件夹结构javax/swing(不需要文件)的类路径中将导致出现错误。我使用的是JDK 10/12(两者都不起作用)。将编译器遵从性设置为1.8会使整个过程再次正常工作。在另一台安装了Eclipse 2018-09的机器上,这可以在编译器遵从性设置为10的情况下运行。

我使用的是Eclipse 2019-03,在(用于测试目的)新安装的Eclipse 2018-09上运行良好。为什么?

编辑2020年6月(解决方案)

正如答案正确指出的那样,这是Java很久以前就内置的限制,直到最近才被强加给我们。我是在将一个有数十个依赖项的大项目迁移到Maven时接触到它的。大约2000年左右就有了图书馆!有“元库”,它由打包在一起的几个库组成。因此,除了确定仍然需要什么(与其余的一起扔进垃圾桶!)、更新违反规则的库或寻找替代库之外,没有其他方法。这花了我很多很多小时。

最后,它成功了,我们有了一个很好的Maven项目要处理。

izkcnapc

izkcnapc1#

这是引起的**

Classpath上的JAR,它包含系统库中也存在的包**java.awt**,但

  • JRE系统库模块路径上*

Java Platform Module System (JPMS)中,不允许在多个模块中使用相同的包。如果使用ModulepathClasspath,则Classpath上的所有内容都作为<unnamed>模块处理(在您的例子中,包java.awt存在于系统模块java.desktop中,也通过模块<unnamed>中的Classpath上的JAR)。

由于无法将JRE系统库模块路径移到类路径(请参阅this answer by Stephan Herrmann for details),因此您只有以下选项:

  • 将编译器合规性设置为1.8(正如您已经提到的)

  • 重建JAR避免JAR内部的Java系统库包名称**(如果使用反射,可能需要额外修改代码):

  • 如果您有源代码,请更改包名称(例如,将包和子包java更改为java_util,将javax更改为javax_util)并重新创建JAR

  • 如果只有.class文件,则必须先反编译.class文件

2exbekwf

2exbekwf2#

因为我打赌很多人都会在模块化Java中遇到这个问题,所以我会提供帮助并给出真正的答案。

在以下情况下发生此错误

  • 您的项目中存在依赖项
  • 包含代码的
  • 使用套餐
  • 也在模块中
  • 被您的项目引用

如果您的项目已经将源代码兼容性设置为类似于Java 12,它将开始执行Java中一直存在的规则:
“不要在您自己的代码中使用属于JDK的包。”

不幸的是,多年来,许多开发人员和供应商都这样做了。我不能再那样做了。

如果您将项目设置为与Java 12源代码兼容,那么Eclipse会添加JDK模块,其中包含所有内容“java.”和“javax.”,甚至“jdk.”、“org.w3c..”。这些包可能正在由您的依赖项或它们的传递依赖项使用。

如何修复

您需要:

  • 看看它在抱怨哪个包裹
  • 并展开包资源管理器中的“项目和外部依赖项”**节点。
  • 找出哪个依赖项正在使用该程序包。
  • 然后,您只需从项目中排除该依赖项。

或者,您可以获取该依赖项的源代码(如果可用),并使用更改后的包重新构建JAR。否则,您必须消除这种依赖,并找到该技术的替代品。疼吧?

如果它是一种可传递的依赖关系,您通常可以将其排除在外。下面是一个基于Gradle的项目的例子。

GradleConfig.xml

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

vngu2lb83#

在我的例子中,这是因为我在POM.xml文件中包含了一个依赖项(ApacheTika)。

在该依赖项中导入时,我必须强制排除包含有错误的类的模块:

<dependency>
        <groupId>org.apache.tika</groupId>
        <artifactId>tika-parsers</artifactId>
        <version>1.24.1</version>
        <exclusions>
            <exclusion>
                <groupId>xml-apis</groupId>
                <artifactId>xml-apis</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

这对我来说很管用。

hiz5n14c

hiz5n14c4#

我想我对这个问题的理解可能会有用。

对于javax.xml.stream下的类,我得到了这个错误,因为旧的Maven项目依赖于xml-apisstax-apigeronimo-stax-api等构件。

从技术上讲,问题是其他人已经说过的:这些构件在不知道Java模块的情况下公开javax.xml.*包(它们是后来发明的),所以包自动转到未命名的模块,这与JDK最新版本中包含的相同的包相冲突,在JDK的最新版本中,这些包有自己的模块名称(因此,相同的包导致两个不同的模块,这是被禁止的。

也就是说,实际的解决方案基本上是使用Maven exclusions从您的项目中移除那些依赖项,并让它改用JDK版本。如果您使用的是另一个构建系统,请使用等效项。

从理论上讲,JDK提供的这些包的最新风格可能不是向后兼容的,实际上,我怀疑这些JSR规范多年来发生了很大变化,到目前为止,我还没有看到它们的替代有任何问题。

相关问题