[ https://issues.apache.org/jira/browse/SUREFIRE-2190?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Slawomir Jaranowski updated SUREFIRE-2190: ------------------------------------------ Fix Version/s: 3.2.0 > optional dependencies and JPMS modules confuse surefire > ------------------------------------------------------- > > Key: SUREFIRE-2190 > URL: https://issues.apache.org/jira/browse/SUREFIRE-2190 > Project: Maven Surefire > Issue Type: Bug > Components: JUnit 5.x support, Maven Surefire Plugin > Affects Versions: 3.1.2 > Reporter: Henning Schmiedehausen > Priority: Major > Fix For: 3.2.0 > > > 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). -- This message was sent by Atlassian Jira (v8.20.10#820010)