1. 程式人生 > 其它 >Jenkins Maven映象Surefire外掛執行失敗

Jenkins Maven映象Surefire外掛執行失敗

這個異常出現在Jenkins流水線中,之前直接依賴於宿主機的maven命令執行正常,但是使用了阿里雲提供的映象`registry.cn-hangzhou.aliyuncs.com/acs/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:

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