I’m trying to migrate a project to Java 12, with
--enable-preview in compiler settings:
<plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> <configuration> <release>12</release> <compilerArgs> <arg>--enable-preview</arg> </compilerArgs> </configuration> </plugin>
And also added it in argLine for surefire and failsafe:
<properties> <argLine>--enable-preview</argLine> </properties>
And do a
mvn clean verify results in:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:3.0.0-M3:test (default-test) on project lombok-jdk10: Execution default-test of goal org.apache.maven.plugins:maven-surefire-plugin:3.0.0-M3:test failed: java.lang.UnsupportedClassVersionError: Preview features are not enabled for com/kirela/lombok/BarTest (class file version 56.65535). Try running with '--enable-preview' -> [Help 1]
I also tried adding argLine directly to surefire/failsafe configuration, but the result is same.
What am I missing here?
I this a bug in surefire/failsafe?
EDIT2: Surefire and failsafe config:
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-plugin</artifactId> <version>3.0.0-M3</version> <configuration> <forkCount>2</forkCount> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-failsafe-plugin</artifactId> <version>3.0.0-M3</version> <executions> <execution> <goals> <goal>integration-test</goal> <goal>verify</goal> </goals> </execution> </executions> <configuration> <forkCount>2</forkCount> </configuration> </plugin>
EDIT3: Minimal working example is here: https://github.com/krzyk/lombok-jdk10-example
The project fails with
--enable-preview, but works when I remove it.
There are two solutions:
MAVEN_OPTS environment variable.
Explanation by the maintainer of surefire:
The argLine does what it has to do without any issue. The plugin runs JUnit filter which finally selects relevant classes to run in one or multiple JVMs. So the JUnit engine runs twice. Once in plugin JVM, and second in the forked JVM.
Due to the classes are compiled with different major or minor version (in bytecode of *.class files) than the version of Java runtime supports in Maven, this JRE fails because Java in Maven does not understand the bytecode. So, it is curious that the same JVM (javac) produced two major versions depending on JVM option and java from the same JVM does not understand it been incompatible for itself. Although version in forked JVM is totally fine and understands the the classes compiled by javac because javac and forked JVM start with the same option –enable-preview. It is the same situation as if you compiled your sources with Java 12 by maven-compiler-plugin using the toolchain and run the whole Maven build with Java 11. So the classes would be compiled with higher version (in bytecode) than the JRE could understand in Maven process.
We have a wish to rework providers and perform the filtering inside of the forked JVM but this is very compilicated change and still questionary.
The issue is that I used
forkCount, it appears surefire doesn’t pass parameters to JVM run in fork.
forkCount parameter from surefire/failsafe configuration.
This will of course cause the tests to run in a single JVM, so if you wanted to speed up the tests using the forks, it won’t work now.