Spring Boot fails to run maven-surefire-plugin ClassNotFoundException org.apache.maven.surefire.booter.ForkedBooter
SpringMavenSpring BootMaven Surefire-PluginSpring Problem Overview
Running maven (3.5.2) build of a Spring Boot 2.0.2.RELEASE applicaton (generated by web initialiser with web dependencies) fails executing the maven-surefire-plugin saying just:
> Error: Could not find or load main class org.apache.maven.surefire.booter.ForkedBooter
>Caused by: java.lang.ClassNotFoundException: org.apache.maven.surefire.booter.ForkedBooter
Why is this happening? Is it a problem in boot + surefire integration = a bug?
For reference, the dependencies that seem relevant are:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/>
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
...
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
Spring Solutions
Solution 1 - Spring
Workaround for the issue was to override Spring Boot's maven-surefire-plugin
definition and set useSystemClassLoader
to false
. Read Surefire docs for more details
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<useSystemClassLoader>false</useSystemClassLoader>
</configuration>
</plugin>
</plugins>
</build>
Solution 2 - Spring
The <useSystemClassLoader>false</useSystemClassLoader>
solution provideded by jediz did allow my surefire tests to run, but broke class loading in some of my Spring Boot integration tests.
The following maven-surefire-plugin configuration worked for me:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<argLine>-Djdk.net.URLClassPath.disableClassPathURLCheck=true</argLine>
</configuration>
</plugin>
Solution 3 - Spring
This is due to a known bug in the Maven Surefire plugin. It was fixed in version 3.0.0-M1, which was released in November 2018. So the simplest and most reliable fix is to upgrade which version of the plugin you use.
Updating the maven-surefire-plugin from 2.12.4 to 3.0.0-M1 worked for me. The project did not explicitly use the plugin, so I had to add a new plugin dependency.
<plugins>
...
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M1</version>
</plugin>
...
</plugins>
Solution 4 - Spring
To me, the solution was to run mvn as
_JAVA_OPTIONS=-Djdk.net.URLClassPath.disableClassPathURLCheck=true mvn clean compile package
Other ideas (giving the system property to the maven argument list, different changes in pom.xml
, settings.xml
) did not work.
Despite that it didn't contain the exact solution, also this answer was very helpful for me to make it clear, that it is an unfortunate cooperation of two independent, alone harmless bugs in the Ubuntu JDK and the Maven Surefire Plugin.
Recent Debian (buster) with the same JDK and Maven versions doesn't seem affected by the problem, but Ubuntu (xenial) did.
The exact solution is coming from this answer.
Update from the future: with Debian Buster is alles okay and this workaround is not needed any more.
Solution 5 - Spring
I was able to remove the maven-surefire-plugin from my POM after adding this to the top of my POM (inside the <project>
node)
<prerequisites>
<maven>3.6.3</maven>
</prerequisites>
Why do I think this is the right answer?
- It specifies the version of Maven that Maven recommends using: https://maven.apache.org/download.cgi
- when you run
mvn versions:display-plugin-updates
it shows that it's taking the maven-surefire-plugin 3.0.0-M3 from super-pom, which so far seems to have this issue fixed. - You don't have to manage individual plugin versions independently going forward. Just your minimum maven version which controls the super-pom version.
Solution 6 - Spring
Adding this to the maven-surefire-plugin I resolved the problem:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<forkCount>0</forkCount>
</configuration>
</plugin>