Problem running tests with enabled preview features in surefire and failsafe
Asked Answered
M

3

31

I'm trying to migrate a project to Java 12, with --enable-preview.

I added --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.

Mime answered 22/3, 2019 at 16:19 Comment(7)
Would be helpful to file an issue with debug logs which would include the exact command line equivalent of what surefire is trying to run.Mannes
What is the values of maven.compiler.source and maven.compiler.target properties?Heartbeat
@IzbassarTolegen Both are 12Strigil
Looks like there is a version 3.0.0-M6 of the surefire plugins now, does that make any difference?Seaworthy
Actually there is no such version in central, and I need to use it, the highest is M3Strigil
You can always check which most recent version is: maven.apache.org/pluginsDeserving
The most reacent version is 3.0.0-M3, there is no newer version releases as of now.Strigil
M
12

There are two solutions:

Add --enable-preview to 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.

Remove the 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.

Mime answered 23/3, 2019 at 8:30 Comment(3)
Maybe forkCount set to 0 could help as well. There was a similar issue possibly reported - SUREFIRE-1528.Mannes
OK, but still doesn't solve my issue, I want fork count to be 1 per cpu core (1C), I can disable forking but that slowes my tests.Strigil
You have to use <argLine>--enable-preview</argLine> in Surefire and <compilerArgs>--enable-preview</compilerArgs> in Maven Compiler Plugin. Thus enable the preview mode in both plugins, or disable the preview in both. It won't work if you enable one but you do not enable the second.Jungian
S
37

This works for me:

  • mvn clean install works (with junit tests)
  • IDEA recognizes module language level correctly as 12 (Preview) - Switch expressions
  • junit tests in IDEA work
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.8.1</version>
        <configuration>
            <release>12</release>
            <compilerArgs>
                <arg>--enable-preview</arg>
            </compilerArgs>
        </configuration>
    </plugin>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.22.2</version>
        <configuration>
            <argLine>--enable-preview</argLine>
        </configuration>
    </plugin>

Environment:

  • Ubuntu 18.04.3 x64

  • IDEA 2019.2.1

  • Maven 3.6.0

  • jdk:

     IMPLEMENTOR="Oracle Corporation"
     JAVA_VERSION="12"
     JAVA_VERSION_DATE="2019-03-19"
    

ADDITION: Similarly this approach works for java 13.

ADDITION: Similarly this approach works for java 17.

Shipmate answered 4/9, 2019 at 21:8 Comment(1)
Five years later... is there not a common Maven property that could enable this for all plugins? I do admire how Maven compiler and surefire plugins do the same thing differently.Amphetamine
M
12

There are two solutions:

Add --enable-preview to 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.

Remove the 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.

Mime answered 23/3, 2019 at 8:30 Comment(3)
Maybe forkCount set to 0 could help as well. There was a similar issue possibly reported - SUREFIRE-1528.Mannes
OK, but still doesn't solve my issue, I want fork count to be 1 per cpu core (1C), I can disable forking but that slowes my tests.Strigil
You have to use <argLine>--enable-preview</argLine> in Surefire and <compilerArgs>--enable-preview</compilerArgs> in Maven Compiler Plugin. Thus enable the preview mode in both plugins, or disable the preview in both. It won't work if you enable one but you do not enable the second.Jungian
A
6

Add a configuration for surefire and failsafe maven plugin

<plugin>
   <artifactId>maven-surefire-plugin</artifactId>
    <configuration>
        <argLine>--enable-preview</argLine>
    </configuration>
</plugin>
<plugin>
    <artifactId>maven-failsafe-plugin</artifactId>
    <configuration>
        <argLine>--enable-preview</argLine>
    </configuration>
</plugin>
Alberthaalberti answered 6/2, 2021 at 21:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.