2

我有一个项目“java11-core”,它生成一个测试 jar 工件以与项目“java11-app”共享。这些项目使用命令行 Maven 构建良好,但在 Eclipse 中,无法找到测试 jar 中共享的类。

版本信息:

  • Apache Maven 3.6.0(命令行和 Eclipse)
  • Java 版本:11.0.1,供应商:甲骨文公司
  • Eclipse IDE:版本:2018-09 (4.9.0)
  • M2E 插件:1.9.1.20180912-1601

我最初将这些项目创建为传统的非 JPMS 项目。这些项目按预期正常编译和运行测试。在我将 module-info.java 添加到 java11-core 和 java11-app 之后,Eclipse 编译器无法识别来自核心项目的共享测试文件。

这是项目结构概述的包资源管理器的快照。

在此处输入图像描述

分别添加了 java11-app 和 java11-core module-info 内容:

module com.java11.app {

    exports com.java11.app;
    requires com.java11.core;
}

module com.java11.core {

    exports com.java11.core;
}

如您所见,我没有从 com.java11.core 导出测试实用程序包。我不想导出测试包,因为这会使测试类公开可用。我也不希望引入一个新的测试项目,因为在现实世界的场景中,这很可能需要测试实用程序和它们协助测试的项目之间的循环依赖关系。

在此处输入图像描述

AppTest.java 中的构建错误。Eclipse 报告的失败很有趣,它并没有声称找不到 CoreTestUtil 类,而是:

The type com.java11.test.core.util.CoreTestUtil is not accessible   AppTest.java    /java11-app/src/test/java/com/java11/app    line 8  Java Problem
CoreTestUtil cannot be resolved                                     AppTest.java    /java11-app/src/test/java/com/java11/app    line 21 Java Problem

我的假设是缺少从 java11-core 导出此包和/或在 java11-app 中缺少此包的要求使 eclipse 认为访问受到限制,即使这些类存在于单独的 test-jar 中.

java11-app 的模块路径显示它包含 java11-core 作为模块,并且无测试代码设置为No

在此处输入图像描述

我知道我正在使用新发布的功能,并且怀疑跨 Eclipse JPMS 项目共享测试类尚不支持。但是,我不确定在哪里寻找支持的更新(Eclipse?M2E 插件)。我也不知道有一种变通方法可以让我在为我的软件项目采用 JPMS 时提高工作效率。

对于那些认为不应以这种方式共享测试实用程序的人...

这个主题被描述为一个最佳实践问题,应该通过将测试实用程序重构到一个单独的模块中来解决。我尊重这种观点,但在尝试遵循该指导时,我发现自己被迫违反其他最佳实践,包括 DRY(不要重复自己)和包之间的循环依赖关系。

在开发一个既有助于对该模块进行有效测试又依赖于该模块的模块时,通常会出现一个测试实用程序。如果这些实用程序被拉出到单独的模块,这将创建一个循环。此外,在测试依赖于该模块的其他模块时,其中一些实用程序同样有用。如果将这些实用程序复制到依赖项的新测试模块,则会创建重复代码。这个推理可能是最初添加 Maven 'test-jar' 支持的原因。

4

2 回答 2

1

Eclipse 不支持每个项目有多个模块信息:在任何源文件夹(main 或 test)中,您必须只有一个模块信息。

从 Eclipse 的角度来看,您唯一的运气是创建一个新的 Java 项目引用另一个并使用其正确的模块信息/导出:

module mod.a {
  exports com.example.a;
  // com.example.a.Main
}

module mod.a.tests { // (1)
  exports com.example.a.tests;
  // com.example.a.tests.MainUtils calling com.example.a.Main
  requires mod.a;
}

在情况(1)中,如果您不使用mod.a.tests: Java will never find ,您将遇到问题com.example.a.Main,可能是因为第二个项目遮蔽了第一个项目。

我不是 OSGI 专家,但我认为这就是为什么大多数 Eclipse 插件确实有一个主要和测试项目的原因 之一org.eclipse.m2e.coreorg.eclipse.m2e.core.tests

但是 module-info 对“补丁”一无所知:您可以在命令行java --patch-module

如您所见,Eclipse 中的两个项目 = 两个 Maven 模块。

在 Maven 的情况下,您当然可以使用相同的构建创建其他工件(我确实认为它会污染依赖项,因为每次您的辅助工件需要依赖项时,它都必须进入公共范围)。

这可以使用 maven-compiler-plugin、maven-shade-plugin 和 maven-jar-plugin 来完成:

  • 我认为您不应该依赖test-jar,因为您想--patch-module通过合并classestest-classes目录来模拟 Java。
  • module-info由于多个;你不想在 Eclipse 中导入这个项目。或者您必须确保其模块信息仅对 Maven 可见(您可以使用配置文件 + m2e.version 来检测 m2e 并禁用它)。
于 2021-07-28T21:22:06.617 回答
0

我完全同意你的看法。当我也可以继承一些 src-test 功能时,为什么我应该只使用一些核心模块的 src-main 代码?

但是如何处理范围问题呢?当我使用“测试”范围时,我失去了与 src-main 代码的关系。当我不使用测试范围时,我失去了与 src-test 代码的关系。

我的核心测试代码不会经常更改,所以为了让这些东西在 Eclipse 中运行,我将 test-jar 安装到我的本地存储库中,一切正常。

于 2019-10-11T18:01:22.527 回答