9

I have a multi-module maven project with three modules core, utils and test-utils

Core has the following dependencies definition

<dependency>
   <groupId>my.project</groupId>
   <artifactId>utils</artifactId>
</dependency>
<dependency>
   <groupId>my.project</groupId>
   <artifactId>test-utils</artifactId>
   <scope>test</scope>
</dependency>

I have added Java 9 module-info.java definitions for all three modules and core's looks like this:

module my.project.core {
   requires my.project.utils;
}

However I cannot figure out how to get core's test classes to be able to see the test-utils classes during test execution. When maven-surefire-plugin attempts the test run I get class not found.

If I add a requires my.project.testutils; to core's module-info.java:

module my.project.core {
   requires my.project.utils;
   requires my.project.testutils; //test dependency
}

Then at compile time I get an error that the my.project.testutils module can't be found (presumably because it's only brought in as a test dependency).

How does one work with test dependencies in a Java 9 modular world? For obvious reason's I don't want my main code to pull in test dependencies. Am I missing something?

kiiadi
  • 381
  • 2
  • 7
  • 3
    I'm not a Maven maven and haven't used the Surefire plugin, but the `module-info.java` with the two `requires` is definitely the wrong direction. Generally, in Java 9, tests are facilitated by 'patching' a module (Maven and Gradle tend to abstract this away). On another note, it is unclear if you have seen this doc re: toolchains? - http://maven.apache.org/surefire/maven-surefire-plugin/java9.html – Michael Easter Nov 07 '17 at 01:12
  • 1
    This doesn't use the Surefire plugin, nor `test` scope (so I won't write it as an answer), but in case this helps, here is a small Java9 example using Maven - https://github.com/codetojoy/WarO_Java_9_Maven – Michael Easter Nov 07 '17 at 01:42
  • @MichaelEaster The part over the patching module is correct there, but the toolchain part seems unrelated to the question. – Naman Nov 07 '17 at 01:46
  • Related: https://stackoverflow.com/questions/46613214/java-9-maven-junit-does-test-code-need-module-info-java-of-its-own-and-wher – ZhekaKozlov Nov 07 '17 at 05:23

1 Answers1

5

With maven and java9, if your my.project.testutils is a test scope dependency, you don't need to explicitly include(requires) it in the module descriptor.


The test dependencies are taken care via the classpath itself. So you can simply remove the testutils and it would be patched by maven while executing tests.

module my.project.core {
   requires my.project.utils;
}

Refer to the slide 30 pertaining to maven-compiler-plugin.

enter image description here

I would also suggest you take a look at Where should I put unit tests when migrating a Java 8 project to Jigsaw and this comment by Robert confirming on the implementation that maven follows.

Edit: Created a sample project drawing an analogy that the main module is same as your core, the dependency on guava is same as your utils and the junit dependency is same as your testutils.

Naman
  • 27,789
  • 26
  • 218
  • 353
  • The example project is a dead link. – Olivier Grégoire Sep 12 '18 at 19:41
  • @OlivierGrégoire ya seems like I've migrated the projects, would try and restore..by that time these answers by Sormuras have a good number of sample links - [this one](https://stackoverflow.com/questions/52110023/how-do-you-organize-tests-in-a-modular-java-project/52110406#52110406) and [this one](https://stackoverflow.com/questions/52162778/how-can-i-test-a-service-provider-implementation-module-with-junit-5/52168316#52168316). – Naman Sep 13 '18 at 02:20
  • 1
    Appears to be true for recent versions of Gradle as well. If you declare a `testImplementation`, `testCompileOnly`, or `testRuntimeOnly` dependency, no module import is required. – Brad Mace Nov 24 '20 at 16:00