Details
-
Bug
-
Status: Closed
-
Major
-
Resolution: Invalid
-
3.7.0
-
None
-
$ mvn -version
Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T20:33:14+02:00)
Maven home: G:\software\apache-maven-3.5.4-bin\apache-maven-3.5.4
Java version: 9.0.4, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-9.0.4
Default locale: fr_FR, platform encoding: Cp1252
OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
$ mvn -version Apache Maven 3.5.4 (1edded0938998edf8bf061f1ceb3cfdeccf443fe; 2018-06-17T20:33:14+02:00) Maven home: G:\software\apache-maven-3.5.4-bin\apache-maven-3.5.4 Java version: 9.0.4, vendor: Oracle Corporation, runtime: C:\Program Files\Java\jdk-9.0.4 Default locale: fr_FR, platform encoding: Cp1252 OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows"
-
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.