7

我正在尝试将一些遗留应用程序迁移到新的 Java 9 模块系统,以加强其封装。

我从外向内开始,假设外围的类具有最少的外部依赖性。

正如你所料,我已经声明了一个非常开放的模块:

module com.example.user {   
    exports com.example.user;
}

这会立即破坏整个项目(在所有类中),突然每个外部依赖项的导入都不再解决(导致超过 1k Java 问题):

导入 com.otherexample 无法解析

导入org.springframework无法解析

等等

同一个项目中的本地包com.example.price仍然有效 - 就像java.util等一样。

所有外部依赖项都由 Maven 管理。在(Eclipse 项目)构建路径中,我仍然可以将它们视为“类路径”依赖项——但只有“模块路径”中的 JRE 系统库。

这两个概念可以共存吗?目前似乎module-info.java在项目中的任何地方都有一个,所有类路径依赖项都停止工作?

我确实读过有关使用自动模块的信息,这似乎暗示您可以通过将它们包含在您的模块路径中来使用旧版/非模块化 jar,然后通过它们的文件名引用它们。他们使用示例:

module com.foo.myapp {
  requires guava;  // guava not yet modularised, so use the filename
}

我找不到太多其他信息,但这似乎与 Eclipse 在自动生成 module-info.java 时使用的约定相匹配,例如:

spring-core-4.3.8.RELEASE.jar

变成:

requires spring.core;

但是,这仍然会导致 Eclipse 报告 Java 错误:

spring.core 无法解析为模块

马文报告:

[ERROR] module-info.java:[39,16] error: module not found: spring.core

...并且项目中具有外部依赖关系的每个类仍然被破坏。

4

1 回答 1

7

感谢Robert Scholte指出更新的 maven-compiler-plugin 3.7.0(我一直在使用 3.6.1),这确实清理了编译目标命令行输出(具有 Java 9 细节),以帮助我了解问题的路径。requires这将报告的错误从每个给我的错误缩小到:

[WARNING] ********************************************************************************************************************
[WARNING] * Required filename-based automodules detected. Please don't publish this project to a public artifact repository! *
[WARNING] ********************************************************************************************************************
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 56 source files to ./target/classes
~~~ snip ~~~
[ERROR] module-info.java error: module not found: foo.bar

匹配日食:

foo.bar cannot be resolved to a module

仅六个自动模块/库(jar)出现错误 - 而不是所有(24)个。伟大的。

在我的 POM 中,我会将源目录的输出拆分为它们自己的输出目录 ( target/classes)。但是,由于该文件夹中的代码(类)未使用/引用的module-info.java依赖项(例如requires spring.core;) - 它无法解析它们。

为什么?基本的 Maven 依赖管理 - 我将这些库的范围限定在默认目标之外(以匹配输出目录拆分)。

一个相当基本的结果 - 但我想我不会是唯一遇到这种情况的人,因为 Java 开始侵犯与传统使用 Maven 重叠的依赖管理的某些方面。

于 2017-10-26T11:27:11.273 回答