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
這是一條簽名的小尾巴: 任何變化都不是突然發生的,都是自己無意間一點一點選擇的。