【问题标题】:Recommended project structure for modular Java with Gradle, JUnit and Mockito使用 Gradle、JUnit 和 Mockito 的模块化 Java 推荐项目结构
【发布时间】:2019-12-08 15:45:12
【问题描述】:

我正在尝试将大型 code base 从 Java 8 迁移到模块化 (JPMS) Java 11,我遇到了巨大的痛苦,并在项目结构和如何使用模块信息方面找到了一致的建议实际生产项目的文件很难。

有问题的项目遵循源文件和测试文件的常规 gradle 结构:

src/main/java/org/abc/...
src/test/java/org/abc/...

我在src/main/java/module-info.java 中有一个module-info.java 文件,这是正确的位置吗?模块化 java 的 quick-startthis 似乎与此相矛盾;但是 other resources 按照我的方式做。

尝试运行如下所示的单元测试时:

@RunWith(MockitoJUnitRunner.class)
public class ABCTest {
    @Mock
    public SomeClass mock;

    ...
}

我明白了:

Unable to make field public SomeClass mock accessible: module org.abc does not "exports org.abc" 
to module org.mockito

这表明我需要在我的module-info.java 文件中添加exports org.abc to org.mockito 但这似乎很笨重而且必须对我的测试树中甚至不是模块一部分的所有子包执行此操作,而且看起来喜欢做错的地方,因为测试不应该与发布 jar 一起导出。

could find 看似最新的指导建议将module-info.[test|java] 文件添加到我的测试树中。这两个文件(.java.test)有什么区别?我在谷歌上找不到任何解释这一点的文章。另外,我应该将内容从main/java/module-info.java 复制到test/java/module-info.test 并保持同步?这似乎很乏味。

我也知道 gradle 还没有对模块化 java 的原生支持,为此必须依赖插件,应该使用哪些“事实上的”插件?

我对可用的信息感到困惑,这似乎是矛盾的,非常低级或在使用 gradle 时不适用。有人可以提供一个使用 mockito、junit、gradle 和模块化 java(版本 9+,最好是 11)的传统源代码布局的示例项目吗?

【问题讨论】:

  • 情况似乎还不清楚。但是已经有dzone.com/articles/…之类的文章了。相关:stackoverflow.com/questions/59117333/…
  • 即使你解决了一个访问问题,你也会遇到 InvalidModuleDescriptorException;由 xpp3:xpp3_min:1.1.4c 工件引起。 JPMS 确定它是无效模块,因为它包含格式错误的服务提供者配置文件。它是少数经常遇到的工件之一,这些工件是任何 JPMS 项目的祸根,不幸的是它们最终会出现在模块路径上。唯一明智的解决方案是重构您的应用程序以使用不同的 XML Pull Parser。 StAX 例如。这是 java.xml 模块中的 JDK 内置的。

标签: java gradle junit mockito java-module


【解决方案1】:

正如您所发现的,Gradle 没有对 JPMS 的内置开箱即用支持。

Gradle 的 JPMS 政策可以总结为来自 Gradle Core Devs 之一的this comment...

„...没有短期的拼图支持工作计划,所以请不要屏住呼吸...“

我已经开发了a plugin that JPMS-enables Gradle and Eclipse

Here is a simple test project 使用 Gradle、JPMS、JavaFX 13、JUnit 4 和 Mockito 实现。 The mrJar JPMS 开发支持插件将这一切联系在一起。

您可以使用原始 Gradle 从命令行运行该测试项目的 :test 任务或 :run 任务。或者按照以下步骤在 Eclipse 中使用测试项目...

  1. 将项目导入Eclipse

  2. 在 Eclipse 的 Gradle Tasks 视图中执行 :eclipse 任务

    • 这是触发 mrJarEclipse Modulefication 功能的原因
  3. 打开项目的属性对话框

    • 转到Java Build Path属性标签
    • 注意标题栏中的通知 (Not all modules could be found. Click Apply to synchronize)
    • 点击Apply按钮同步模块路径
  4. 执行:test任务

    • 或者,从 Package Explorer 上下文菜单中执行 Run As Gradle Test
    • 或者同样,执行 :check 任务是另一个与 :eclipse 具有相同 Eclipse Modulefication 效果的选项,:testRun As Gradle Test

The recording 可能有助于阐明在 Eclipse 中运行单元测试和 JavaFX 应用程序所需遵循的步骤。

希望您会发现附加的测试项目非常简单。但如果你卡住了,还有更详细的使用说明和屏幕录像in this Gradle Communnity Forum thread

我也很高兴在该论坛主题中与您互动,并澄清视频或任何步骤中可能不明显的任何内容。


另外,here's a github repository 带有您的项目的完全启用 JPMS 的副本@EmilyL...

【讨论】:

    【解决方案2】:

    我的另一个答案是对您的“有人可以提供一个使用 mockito、junit、gradle 和模块化 java(版本 9+,最好是 11)的传统源代码布局的示例项目吗?”请求。

    但您可能还想知道标题中问题的答案。

    TL;DR:您遇到的两种目录结构都同样合法。但是对于单模块项目,传统的 src/main/java 就足够了。

    长答案

    不常见的 src/com.foo.mymodule/io/bar/apackage 结构是一种在与模块同名的文件夹中整齐有序地组织模块的方法。然后模块的包像往常一样进入该平面模块名称目录。

    然而,这不仅仅是一种风格选择。以不太典型的方式组织模块有一些实用的技术优势。

    JPMS --module-source-path 命令行选项可以一次编译多个不同的模块。所以你可以像这样组织多个模块......

    .
    .
    └── src
        ├── com.foo.mymodule
        │   ├── module-info.java
        │   └── io
        │       └── bar
        │           └── apackage
        │               ├── *.java
        │               └── ...
        ├── net.other.module
        │   ├── module-info.java
        │   └── org
        │       ├── example
        │       │   └── yadda
        │       │       ├── *.java
        │       │       └── ...
        │       └── another
        │           └── pkg
        │               ├── *.java
        │               └── ...
        ├── mr.jar
        │   ├── module-info.java
        │   └── com
        │       └── lingocoder
        │           └── plugin
        │               ├── *.java
        │               └── ...
        ├── and.so.forth
        └── ...            
    

    然后javac -d mods --module-source-path src ...可以编译所有嵌套在src下的模块的所有代码。

    它将镜像 src 下的目录结构,同时将生成的类文件存储在目标目录中(mods 在我的示例中)。

    例如,为 net.other.module 模块生成的所有类文件都将存储在 mods/net.other.module 目录中;包层次结构在其下镜像。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 2018-12-23
      • 1970-01-01
      • 2012-03-16
      相关资源
      最近更新 更多