Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Fixed
-
3.1.2
-
None
Description
The surefire plugin, when executing tests for JPMS code, patches the test code "into" the module under test (using --patch-module). This work for compile+runtime dependencies (`requires`) but not for compile required/runtime optional dependencies (requires static).
The plugin only adds the module under test using --add-modules module.under.test.id to the JVM that is executing the test classes. As requires static dependencies are not loaded transitively, any dependency that is optional for the main artifact but required for test code is not found.
clone and build the test repo: https://github.com/hgschmie/msurefire2190
This repo contains three artifacts with identical code:
thing1 builds a main artifact without JPMS
thing2 builds a main artifact with a strong (requires) dependency on jakarta.annotation.
thing3 builds a main artifact with a compile-only (requires static) dependency on jakarta.annotation.
The code and its test classes are otherwise identical.
Running mvn -DskipTests clean install builds all three modules and the test code.
Running mvn surefire:test passes the tests in the first two modules but fails in the third.
Explanation:
The surefire plugin, when it executes tests using JPMS adds all referenced modules to the module path (in this case the module under test itself and the jakarta.annotations-api jar). It then adds the main module using --add-modules and patches this module with the test classes (using -patch-module, so that the test classes execute as part of the module.
In case of a compile+runtime (requires) relationship, the JVM will find the required JPMS module on the module path and add it as accessible. This is why the "thing2" tests pass.
In case of a compile only/runtime optional (requires static) relationship, the JVM will not add the module transitively as it is considered a compilation-only dependency. For the code under test to be able to access the classes from jakarta.annotation, they must be declared as a module. However, the test code only adds the module under test with --add-modules. So the test classes do not find any classes from the jakarta.annotation module and the test fails.
The fix is simple: Instead of just adding the module under test using --add-modules, the surefire plugin should use -add-modules ALL-MODULE-PATH.
Which is correct, because the code is not looking for compile time only dependencies but actual runtime dependencies where the code under execution may also need to access optional runtime dependencies (see
https://nipafx.dev/java-modules-optional-dependencies/ for a slightly longer explanation).
Attachments
Issue Links
- links to