简体   繁体   中英

JUnit tests do not seem to get run with --add-modules=jdk.incubator.vector from Maven

I've added SIMD code to a Java application that uses Maven to build, and now I have to run it like this:

mvn exec:java -Dexec.mainClass="com.path.to.app.MainClass" -Dexec.classpathScope=runtime -Dexec.systemProperties="-da --add-modules=jdk.incubator.vector"

I also created .mvn/jvm.config file with the following content:

--add-modules=jdk.incubator.vector

Finally, in pom.xml I added the following under project/build/plugins :

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.10.1</version>
            <configuration>
                <compilerArgs>
                    <arg>--add-modules=jdk.incubator.vector</arg>
                </compilerArgs>
            </configuration>
        </plugin>

The application itself runs from Eclipse and from command-line with Maven as shown above. However, if I run mvn install , the JUnit tests fail:

java.lang.NoClassDefFoundError: jdk/incubator/vector/Vector
...
Caused by: java.lang.ClassNotFoundException: jdk.incubator.vector.Vector
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)

All the above steps were found on the inte.net. I couldn't find how to fix JUnit. Please, suggest.

OpenJDK 19, Maven 3.8.6, Ubuntu 20.04, JUnit is enabled in pom.xml as follows:

<junit.version>4.13.2</junit.version>
...
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>${junit.version}</version>
        <scope>test</scope>
    </dependency>

As far as I can judge, the compilation is fine. That means the maven-compiler-plugin is properly configured, ie <arg>--add-modules=jdk.incubator.vector</arg> is picked up.

The java.lang.NoClassDefFoundError happens at runtime, ie when the test is running. That obviously means --add-modules=jdk.incubator.vector is not picked up. I believe the reason is the maven-surefire-plugin not configured properly so that it doesn't propagate that value to the JVM that actually runs the test. By default, that JVM is different from the one running Maven itself. This is managed by the forkCount parameter :

The default setting is forkCount=1/reuseForks=true, which means that maven-surefire-plugin creates one new JVM process to execute all tests in one Maven module.

So, if you want to keep it that way ( forkCount > 0) then you have to properly configure the maven-surefire-plugin . Like in the following example:

<plugins>
[...]
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>3.0.0-M7</version> <!-- pick your own version -->
    <configuration>
        <forkCount>1</forkCount>
        <argLine>--add-modules=jdk.incubator.vector</argLine>
    </configuration>
  </plugin>
[...]
</plugins>

.mvn/jvm.config doesn't work in your case because this configuration is for Maven JVM as sort of alternative for MAVEN_OPTS :

So no need anymore for MAVEN_OPTS... You don't need to use these options in MAVEN_OPTS or switch between different configurations.

About MAVEN_OPTS:

This variable contains parameters used to start up the JVM running Maven and can be used to supply additional options to it.

So, if forking is disabled ( forkCount = 0) then it will work because there will be only one JVM for everything. Otherwise, only the system properties get passed to a forked JVM :

System property variables from the main maven process are passed to the forked process as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM