[ 
https://issues.apache.org/jira/browse/SUREFIRE-2190?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Henning Schmiedehausen resolved SUREFIRE-2190.
----------------------------------------------
    Fix Version/s: 3.x-candidate
       Resolution: Fixed

> 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
>            Assignee: Henning Schmiedehausen
>            Priority: Major
>             Fix For: 3.x-candidate, 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)

Reply via email to