Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem running tests with enabled preview features in surefire and failsafe

Tags:

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.

like image 945
Krzysztof Krasoń Avatar asked Mar 22 '19 16:03

Krzysztof Krasoń


People also ask

What is the difference between maven Surefire and maven failsafe plugins?

maven-surefire-plugin is designed for running unit tests and if any of the tests fail then it will fail the build immediately. maven-failsafe-plugin is designed for running integration tests, and decouples failing the build if there are test failures from actually running the tests.

What is the use of maven failsafe plugin?

The Failsafe Plugin is used during the integration-test and verify phases of the build lifecycle to execute the integration tests of an application. The Failsafe Plugin will not fail the build during the integration-test phase, thus enabling the post-integration-test phase to execute.

How do I enable Java preview?

If you want to use preview features in the latest versions of Java in IntelliJ IDEA, you need to set the language level to "Preview". Go to Project Structure, ⌘; (macOS) or Ctrl+Alt+Shift+S (Windows/Linux), make sure you have the correct JDK selected, and pick the "Preview" option from the Language Level dropdown.

What is maven surefire plugin used for?

The Surefire Plugin is used during the test phase of the build lifecycle to execute the unit tests of an application. It generates reports in two different file formats: Plain text files (*. txt)


2 Answers

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.

like image 105
jd_abcde Avatar answered Oct 12 '22 01:10

jd_abcde


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.

like image 20
Krzysztof Krasoń Avatar answered Oct 12 '22 01:10

Krzysztof Krasoń