使用 Java 11 在 Eclipse 中混合模块化和非模块化开发

Posted

技术标签:

【中文标题】使用 Java 11 在 Eclipse 中混合模块化和非模块化开发【英文标题】:Mixed Modular and Non-Modular Development in Eclipse using Java 11 【发布时间】:2019-09-02 10:18:18 【问题描述】:

我已经有一段时间没有进行 Java 编程了,我很惊讶在项目拼图之后回到它,整个景观对我来说都是陌生的。

我在使用具有混合模块化和非模块化环境的 Eclipse (2018-09, 4.9.0) 标准 Java 项目时遇到问题。具体来说,我正在尝试使用 Eclipse 平台(没有 Gradle 或 Maven 的基础 Java 项目)结合 JavaFX 11(模块化)和 Apache POI 4.1(非模块化)。

在我的 module-info.java 中,我有以下内容,

module myapp 
        requires javafx.base;
        requires javafx.graphics;
        requires javafx.fxml;
        requires javafx.controls;
        requires javafx.web;

        exports myapp.gui;

        opens myapp.gui to javafx.fxml;

我发现无论我有 Apache POI 代码,我都会在 Eclipse 中收到以下错误

The import cannot be resolved

使用为Apache POI创建的自动模块在module-info.java中添加以下内容,就像这样,

        requires poi;

在 Eclipse 中产生一个警告,表明自动模块不稳定,这似乎被识别但继续产生无法解决的错误。

我也尝试将主 POI jar 文件放在类路径中,而不是模块路径,但无济于事。

涉及与 UI 分离的 Apache POI 的代码有效。我只需要删除 module-info.java 的使用,我认为它会将项目置于某种遗留开发模式中,没有模块化?

谁能给我一个关于我做错了什么的指针并指导我设置一个混合模块化和非模块化库的项目?

提前致谢。

【问题讨论】:

【参考方案1】:

如果默认包中有module-info.java 文件,则您的代码将封装在模块中。 在模块中使用 JAR 的东西

JAR 必须位于 Modulepath 和 该模块必须在module-info.java:requires <module_name>;中明确声明为要求

否则,导入语句无法解析。 Classpath 上的任何项目都不能从模块访问; Modulepath 上没有 requires ... in module-info.java 的任何内容都不能在模块中使用。因此,在您的情况下,如果没有 requires poi;(并且没有 Modulepath 上的 POI 库),它将无法工作。

“自动模块 '...' 的名称不稳定” 警告只是一个提示,POI JAR 没有构建为模块,而是使用作为一个模块。实际上,这意味着如果您重命名 JAR 文件,模块名称也可以更改,您必须修改 module-info.java 文件。从技术上讲,POI JAR 既不包含 module-info.class 文件,也不包含带有 Automatic-Module-Name: ... 行的 META-INF/MANIFEST.MF 文件。所以模块名称poi 是从JAR 的文件名派生而来的。 “自动模块 '...' 的名称不稳定” 警告可以在 Module 的 Project > Properties: Java Compiler > Errors/Warnings 中关闭 部分。

总而言之,您没有混合的模块化和非模块化依赖项。相反,遗留 JAR 通过从文件名派生模块名自动成为模块。在这种情况下,Eclipse 默认会警告您,只需更改该 JAR 的文件名即可破坏该应用程序。

【讨论】:

感谢您的回复,如果即使这样 Eclipse 仍然无法编译代码,是否意味着所有迹象都表明 Eclipse 中存在问题? @adizen 不。我已经重写了我的答案。我希望现在更清楚了。 @howlger 我在 Java Mail activation.jar 文件中遇到了同样的错误。感谢您的完整回答。【参考方案2】:

所以,事实证明。我确实搞砸了。 POI库中有5个相互依赖的jar文件导致错误“无法解析导入”

一旦我在 module-info.java 中包含所有 5 个文件,项目就会编译。

        requires poi.excelant;
        requires poi.ooxml;
        requires poi.ooxml.schemas;
        requires poi.scratchpad;
        requires poi;

我确信并非所有这些都是必需的,但无论如何我都包括了所有这些以防万一。

感谢大家阅读并确认我没有做任何事情来破坏 Eclipse。

【讨论】:

以上是关于使用 Java 11 在 Eclipse 中混合模块化和非模块化开发的主要内容,如果未能解决你的问题,请参考以下文章

Scala和Java混合项目搭建:(Eclipse)

如何在eclipse中为java代码添加快捷键

如何在 Eclipse PDE 中表达项目间依赖关系

在没有模运算符的Java中测试偶数

Java 11、JavaFX、Gradle、Eclipse,令人讨厌的失败消息

Eclipse 创建 Java 接口---Eclipse教程第11课