Uploaded image for project: 'Maven Compiler Plugin'
  1. Maven Compiler Plugin
  2. MCOMPILER-348

Can't make test-scoped dependencies work with Java 9 modules

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Invalid
    • 3.7.0
    • None
    • Important

    Description

      In short

      With Java 9 if I declare both the test-scoped dependency and the Java 9 modules the test doesn't compile anymore (mvn clean install output):

      [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile (default-testCompile) on project clientmod: Compilation failure: Compilation failure:
      [ERROR] /G:/projets/wires/wires/wires/clientmod/src/test/java/qux/DerivedTest.java:[3,11] package api does not exist
      [ERROR] /G:/projets/wires/wires/wires/clientmod/src/test/java/qux/DerivedTest.java:[11,13] cannot find symbol
      [ERROR]   symbol:   class Base
      [ERROR]   location: class qux.DerivedTest
      [ERROR] -> [Help 1]
      

      That same test DerivedTest compiles and runs just fine in IntelliJ! So it's probably worth it to look at the different flags that Maven passes to javac and java compared to IJ?

      Explanation of the 2 modules, and what fails

      I have a java 9 maven project with 2 modules: apimod and clientmod. Module clientmod depends on module apimod (those modules are both Maven modules and Java 9 modules).

      Also, i want module clientmod to be able to reuse not only production code from apimod, but also test code. This is a common pattern, that I used many times with Java 8. With Java 9 (it's the same with Java 10) it also works fine, as long as i don't declare module-info.java (that is, as long as I don't run with the module system).

      But as soon as I do, enabling the test dependency seems to disable the production dependency: api.Base (an src/main class of module apimod) is no longer visible from qux.DerivedTest (an src/test class of module clientmod). The test doesn't compile anymore. (Note that every class is in a different package to eliminate split packages as a cause of the problem)

      This is with: Java 9.0.4 (it's the same with Java 10), Maven 3.5.3, maven-compiler-plugin 3.7.0

       

      A project to reproduce the issue

      The code

      I "dichotomized" the issue with a failing test in a branch:

      git clone https://github.com/vandekeiser/wires.git
      git checkout MCOMPILER_ISSUE2
      mvn clean install

      -> BUILD FAIL (compilation error in the test of clientmod)

      The Maven test-scoped dependency

      I want module clientmod to be able to reuse not only production code from apimod but also test code. With Maven you do it like that (clientmod/pom.xml):

      <dependency>
          <groupId>fr.cla</groupId>
          <artifactId>apimod</artifactId>
          <version>${project.version}</version>
          <classifier>tests</classifier>
          <scope>test</scope>
      </dependency>
      

      The Java 9 modules

      module apimod {
          exports api;
      }
      
      module clientmod {
          requires apimod;
      }
      

      The failure when trying to enable both module systems

      With Java 9 if I declare both the test-scoped dependency and the Java 9 modules the test doesn't compile anymore (mvn clean install output):

      [ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.7.0:testCompile (default-testCompile) on project clientmod: Compilation failure: Compilation failure:
      [ERROR] /G:/projets/wires/wires/wires/clientmod/src/test/java/qux/DerivedTest.java:[3,11] package api does not exist
      [ERROR] /G:/projets/wires/wires/wires/clientmod/src/test/java/qux/DerivedTest.java:[11,13] cannot find symbol
      [ERROR]   symbol:   class Base
      [ERROR]   location: class qux.DerivedTest
      [ERROR] -> [Help 1]
      

      My analysis so far

      It works if i remove the test-scope dependency

      If i comment the test-dependency, mvn clean install passes:

      //import baz.BaseTest;
      DerivedTest /*extends BaseTest*/
      
      <!--Comment the following to make mvn clean install pass (but then you can't have DerivedTest extends BaseTest)-–>
      
      <!--<dependency>-->
      <!--<groupId>fr.cla</groupId>-->
      <!--<artifactId>apimod</artifactId>-->
      <!--<version>${project.version}</version>-->
      <!--<classifier>tests</classifier>-->
      <!--<scope>test</scope>-->
      <!--</dependency>-->
      
      
      

       

      Trying to pass explicit module flags to the JVM

      After asking here: https://stackoverflow.com/questions/50122838/cant-make-maven-test-scoped-dependencies-work-with-java-9-nor-10-modules

      I tried the following flags to move apimod-1.0-SNAPSHOT-tests.jar from -module-path to -patch-module clientmod, it compiles but then surefire fails so it must not be right either (anyway passing all those flags is fragile):

       <!--This makes the test compile even with the test-scoped dependency present, but then surefire fails (so probably those flags are incorrect too)-->
      
      <compilerArgs>
          <arg>--module-source-path=./*/src/main/java;./*/src/test/java/;</arg>
          <arg>
              --source-path=/G/projets/wires/wires/wires/apimod/src/main/java;/G/projets/wires/wires/wires/apimod/src/test/java;/G/projets/wires/wires/wires/clientmod/src/test/java;/G/projets/wires/wires/wires/clientmod/src/main/java;
          </arg>
          <arg>-Xlint:all</arg>
          <arg>
              --patch-module=clientmod=/G/projets/wires/wires/wires/clientmod/target/classes;/G/projets/wires/wires/wires/clientmod/src/test/java;/G/projets/wires/wires/wires/apimod/target/apimod-1.0-SNAPSHOT.jar;/G/projets/wires/wires/wires/apimod/target/apimod-1.0-SNAPSHOT-tests.jar;
          </arg>
          <arg>--add-reads=apimod=ALL-UNNAMED</arg>
          <arg>--add-reads=clientmod=ALL-UNNAMED</arg>
          <arg>--add-exports=apimod/api=ALL-UNNAMED</arg>
          <arg>--add-exports=clientmod/client=ALL-UNNAMED</arg>
          <arg>--add-modules=apimod</arg>
      </compilerArgs>
      

      Just mentioning this in case the problem would be wrong javac flags.

      Attachments

        1. MCOMPILER-348-reproduce.7z
          1.06 MB
          foo bar
        2. mvn-X-clean-install-output.txt
          167 kB
          foo bar

        Activity

          People

            rfscholte Robert Scholte
            vandekeizer foo bar
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: