Jenkins Maven镜像Surefire插件运行失败
Photo by Pixabay from Pexels
这个异常出现在Jenkins流水线中,之前直接依赖于宿主机的maven命令运行正常,但是使用了阿里云提供的镜像registry.cn-hangzhou.aliyuncs.com/acs/maven
却失败了。提示Surefire提前退出运行
org.apache.maven.surefire.booter.SurefireBooterForkException: The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
完整异常堆栈如下:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.22.2:test (default-test) on project test: There are test failures.
[ERROR]
[ERROR] Please refer to /var/jenkins_home/workspace/Test/target/surefire-reports for the individual test results.
[ERROR] Please refer to dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
[ERROR] Command was /bin/sh -c cd /var/jenkins_home/workspace/Test && /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java -jar /var/jenkins_home/workspace/Test/target/surefire/surefirebooter3126193174777161031.jar /var/jenkins_home/workspace/Test/target/surefire 2021-09-27T09-18-34_239-jvmRun1 surefire6322654167796133591tmp surefire_03455431665096220795tmp
[ERROR] Error occurred in starting fork, check output in log
[ERROR] Process Exit Code: 1
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: The forked VM terminated without properly saying goodbye. VM crash or System.exit called?
[ERROR] Command was /bin/sh -c cd /var/jenkins_home/workspace/Test && /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java -jar /var/jenkins_home/workspace/Test/target/surefire/surefirebooter3126193174777161031.jar /var/jenkins_home/workspace/Test/target/surefire 2021-09-27T09-18-34_239-jvmRun1 surefire6322654167796133591tmp surefire_03455431665096220795tmp
[ERROR] Error occurred in starting fork, check output in log
[ERROR] Process Exit Code: 1
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:669)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:282)
[ERROR] at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:245)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1183)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1011)
[ERROR] at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:857)
[ERROR] at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:137)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:210)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:156)
[ERROR] at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:148)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:117)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:81)
[ERROR] at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build(SingleThreadedBuilder.java:56)
[ERROR] at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:128)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:305)
[ERROR] at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:192)
[ERROR] at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:105)
[ERROR] at org.apache.maven.cli.MavenCli.execute(MavenCli.java:956)
[ERROR] at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:288)
[ERROR] at org.apache.maven.cli.MavenCli.main(MavenCli.java:192)
[ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
[ERROR] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
[ERROR] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
[ERROR] at java.lang.reflect.Method.invoke(Method.java:498)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:289)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:229)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:415)
[ERROR] at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:356)
[ERROR]
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoExecutionException
堆栈的开头部分提示我们可以在工作空间找到 dumpstream 的异常描述信息,从构建记录中找到对应的surefire目录:
可以看到类似 2021-09-27T09-18-34_239.dumpstream 的dump文件,内容:
# Created at 2021-09-27T09:18:35.035
Error: Could not find or load main class org.apache.maven.surefire.booter.ForkedBooter
到这里问题就明了了,流水线代码没有问题,只是因为maven镜像版本的问题,参考StackOverflow的回答:
https://stackoverflow.com/questions/53010200/maven-surefire-could-not-find-forkedbooter-class
To fix it (in 2018), update your openjdk to the latest version, at least 8u191-b12. In case this issue reappears in 2020, it is likely that the default behavior of openjdk was changed, and you will then need to update the maven surefire plugin.
This was a now fixed bug in the openjdk-8 package (behaviour deviates from upstream significantly without need; missing the upstream patch to revert back to disabling a security check) that you just upgraded to. But it is also a bug in the surefire plugin, SUREFIRE-1588, supposedly fixed in surefire 3.0.0-M1: it apparently is using absolute paths in a place where Java will in the future only allow relative path names (and Debian activated the future behavior already).
The package version 8u181-b13-2 states:
- Apply patches from 8u191-b12 security update.
Note that 191-b12 != 181-b13. The 191-b12 security patches were just out a few days ago, and apparently the maintainers wanted to get them to you fast. Updating completely to 191-b12 will likely need additional testing (well, so should have this upload, apparently).
There had been several workaounds:
- You can install the previous package from snapshots.d.o instead. After downgrading, you can forbid the broken version (if you are using aptitude and not
apt
) usingsudo aptitude forbid-version openjdk-8-jre-headless
. For regular "apt" I didn't see a similar forbid mechanism, so you would likely need to use apt pinning to prevent this upgrade from being reinstalled (or you just keep on downgrading again, I hope this will be resolved soon).- According to bug tracking, setting the property
-Djdk.net.URLClassPath.disableClassPathURLCheck=true
with any of the usual methods (e.g.,JAVA_FLAGS
) should also help. But I have not verified this myself. You can apparently even add the workaround to~/.m2/settings.xml
to get it enabled for all your Maven builds easily.
解决方案也很简单,基于其他版本的maven镜像自定义maven配置:
# Dockerfile
FROM maven:3.6.3-jdk-11
LABEL maintainer fengxiao
COPY settings.xml /usr/share/maven/ref/
接下来配置自己的maven Setting文件,然后构建并更换掉流水线中使用的maven镜像即可:
docker build -t ali-maven:3.6.3-jdk-11 -t your-maven-name:3.6.3-jdk-11 .
docker image push your-maven-name:3.6.3-jdk-11