Java 调试万无一失的策略“分叉的 VM 没有说再见就终止了。VM 崩溃或 System.exit 被调用?”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20642673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 03:18:56  来源:igfitidea点击:

Strategy for debugging surefire "The forked VM terminated without saying properly goodbye. VM crash or System.exit called ?"

javamavenmaven-surefire-plugin

提问by Nitzan Volman

I am working on a rather complex java project with many dependencies and many unit tests.

我正在开发一个相当复杂的 java 项目,它有许多依赖项和许多单元测试。

I am using java 1.6.0_65 on mac (mavericks) with maven 3.0.5 with maven-surefire-plugin:2.16 running in several forks. My problem is that running this setup with several forks causes a fork to exit with:

我在 mac(小牛)上使用 java 1.6.0_65 和 maven 3.0.5,maven-surefire-plugin:2.16 在几个分支中运行。我的问题是使用多个 fork 运行此设置会导致 fork 退出:

"The forked VM terminated without saying properly goodbye. VM crash or System.exit called ?"

“分叉的 VM 没有说再见就终止了。VM 崩溃或 System.exit 被调用?”

running this with only one fork does not produce the problem (and everything passes)

只用一个叉子运行它不会产生问题(一切都过去了)

There is some information out there about this problem including this StackOverflow questionand this surefire bug(which seems to be solved by now)

有一些关于这个问题的信息,包括这个 StackOverflow 问题这个万无一失的错误(现在似乎已经解决了)

I am aware that the "Answer" to this situation is to find what in my code calls System.exit() - Nothing i could find.

我知道这种情况的“答案”是找到我的代码中调用 System.exit() 的内容 - 我找不到任何东西。

Or what causes my JVM to crash - there are no hs_pid crash reports.

或者是什么导致我的 JVM 崩溃 - 没有 hs_pid 崩溃报告。

My Question is what what kind of strategy can i use to find a locate this cause?To clarify, I am not interested in the answer noted above, but a way to find where it is originating from. (Or even better a different answer altogether to what might be causing this )

我的问题是我可以使用什么样的策略来找到这个原因?澄清一下,我对上面提到的答案不感兴趣,而是一种找到它起源的方法。(或者甚至更好的完全不同的答案可能导致这种情况)



my Surefire configuration is: (but i did try other combinations)

我的 Surefire 配置是:(但我确实尝试了其他组合)

<parallel>classes</parallel>
<threadCount>1</threadCount>
<forkCount>1C</forkCount>
<reuseForks>false</reuseForks>
<useSystemClassLoader>false</useSystemClassLoader>
<useManifestOnlyJar>true</useManifestOnlyJar>
<useFile>true</useFile>
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<runOrder>alphabetical</runOrder>


Update #1adding the relevant out put after running the maven goal with --debug (-X)

使用 --debug (-X) 运行 maven 目标后,更新 #1添加相关输出

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.16:test (default-test) on project event-logger: ExecutionException; nested exception is java.util.concurrent.ExecutionException: java.lang.RuntimeException: The forked VM terminated without saying properly goodbye. VM crash or System.exit called ?
[ERROR] Command was/bin/sh -c cd /Users/nitzan/work/nitzan_5_parallel_tests/event-logger && /Library/Java/JavaVirtualMachines/1.6.0_65-b14-462.jdk/Contents/Home/bin/java org.apache.maven.surefire.booter.ForkedBooter /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire5107531798951225850tmp /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire_12561116468761732560tmp
[ERROR] -> [Help 1]
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.16:test (default-test) on project event-logger: ExecutionException; nested exception is java.util.concurrent.ExecutionException: java.lang.RuntimeException: The forked VM terminated without saying properly goodbye. VM crash or System.exit called ?
Command was/bin/sh -c cd /Users/nitzan/work/nitzan_5_parallel_tests/event-logger && /Library/Java/JavaVirtualMachines/1.6.0_65-b14-462.jdk/Contents/Home/bin/java org.apache.maven.surefire.booter.ForkedBooter /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire5107531798951225850tmp /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire_12561116468761732560tmp
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:213)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
    at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
    at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
    at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
    at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
    at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
    at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
    at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
    at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
    at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
    at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
    at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: org.apache.maven.plugin.MojoFailureException: ExecutionException; nested exception is java.util.concurrent.ExecutionException: java.lang.RuntimeException: The forked VM terminated without saying properly goodbye. VM crash or System.exit called ?
Command was/bin/sh -c cd /Users/nitzan/work/nitzan_5_parallel_tests/event-logger && /Library/Java/JavaVirtualMachines/1.6.0_65-b14-462.jdk/Contents/Home/bin/java org.apache.maven.surefire.booter.ForkedBooter /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire5107531798951225850tmp /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire_12561116468761732560tmp
    at org.apache.maven.plugin.surefire.SurefirePlugin.assertNoException(SurefirePlugin.java:198)
    at org.apache.maven.plugin.surefire.SurefirePlugin.handleSummary(SurefirePlugin.java:188)
    at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:852)
    at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:720)
    at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
    at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
    ... 25 more
Caused by: org.apache.maven.surefire.booter.SurefireBooterForkException: ExecutionException; nested exception is java.util.concurrent.ExecutionException: java.lang.RuntimeException: The forked VM terminated without saying properly goodbye. VM crash or System.exit called ?
Command was/bin/sh -c cd /Users/nitzan/work/nitzan_5_parallel_tests/event-logger && /Library/Java/JavaVirtualMachines/1.6.0_65-b14-462.jdk/Contents/Home/bin/java org.apache.maven.surefire.booter.ForkedBooter /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire5107531798951225850tmp /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire_12561116468761732560tmp
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.runSuitesForkPerTestSet(ForkStarter.java:316)
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:169)
    at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:958)
    at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:822)
    ... 28 more
Caused by: java.util.concurrent.ExecutionException: java.lang.RuntimeException: The forked VM terminated without saying properly goodbye. VM crash or System.exit called ?
Command was/bin/sh -c cd /Users/nitzan/work/nitzan_5_parallel_tests/event-logger && /Library/Java/JavaVirtualMachines/1.6.0_65-b14-462.jdk/Contents/Home/bin/java org.apache.maven.surefire.booter.ForkedBooter /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire5107531798951225850tmp /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire_12561116468761732560tmp
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
    at java.util.concurrent.FutureTask.get(FutureTask.java:83)
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.runSuitesForkPerTestSet(ForkStarter.java:300)
    ... 31 more
Caused by: java.lang.RuntimeException: The forked VM terminated without saying properly goodbye. VM crash or System.exit called ?
Command was/bin/sh -c cd /Users/nitzan/work/nitzan_5_parallel_tests/event-logger && /Library/Java/JavaVirtualMachines/1.6.0_65-b14-462.jdk/Contents/Home/bin/java org.apache.maven.surefire.booter.ForkedBooter /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire5107531798951225850tmp /Users/nitzan/work/nitzan_5_parallel_tests/event-logger/target/surefire/surefire_12561116468761732560tmp
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:485)
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:352)
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.access0(ForkStarter.java:85)
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.call(ForkStarter.java:288)
    at org.apache.maven.plugin.surefire.booterclient.ForkStarter.call(ForkStarter.java:283)
    at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
    at java.util.concurrent.FutureTask.run(FutureTask.java:138)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
    at java.lang.Thread.run(Thread.java:695)
[ERROR] 
[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/MojoFailureException

回答by Nitzan Volman

Writing here the strategy that i used to help others who are stuck with this problem.

在这里写下我用来帮助遇到这个问题的其他人的策略。

It is possible to leverage the SecurityManager to throw an exception when System.exit() is called. you can then examine the stack trace to see exactly who called exit(). This is especially useful if the call to exit was made from code hidden inside one of the jars you are depending on and not from your own code.

当 System.exit() 被调用时,可以利用 SecurityManager 抛出异常。然后,您可以检查堆栈跟踪以查看究竟是谁调用了 exit()。如果退出调用是由隐藏在您所依赖的 jar 中的代码而不是您自己的代码中进行的,则这尤其有用。

private static void forbidSystemExitCall() {
    final SecurityManager securityManager = new SecurityManager() {
        public void checkPermission( Permission permission ) {
            if( permission.getName().startsWith("exitVM") ) {
                throw new RuntimeException("Something called exit ") ;
            }
        }
    } ;
    System.setSecurityManager( securityManager ) ;
}  

回答by kc2001

Steps:

脚步:

(1) Run mvn with the -eand -Xoptions to get more debug information.

(1) 使用-e-X选项运行 mvn以获取更多调试信息。

(2) Look for "Error" in the output. In my case, when I ran the mvn command, part of the output included:

(2) 在输出中查找“错误”。就我而言,当我运行 mvn 命令时,部分输出包括:

[ERROR] Command wascmd.exe /X /C "C:\dev\dev-tools\.....

(3) Execute the problematic command directly in the command shell.

(3)直接在命令shell中执行有问题的命令。

In my case, executing

就我而言,执行

cmd.exe /X /C "C:\dev\dev-tools\....

from the command line resulted in an OutOfMemoryError.

从命令行导致 OutOfMemoryError。

回答by NoDataFound

Following Maven Surefire documentation, you can execute the forked VM in debug mode, if it always fails. You can then debug your code until it exit.

按照 Maven Surefire 文档,您可以在调试模式下执行分叉的 VM ,如果它总是失败。然后您可以调试您的代码,直到它退出。

回答by Ted_Zactly

What you may want to check is the argline setting for surefire or failsafe in build/pluging/plugin config in your pom. I had something improper in there that caused the forked vm to fail (Ironically, i put maven.failsafe.debug in there to help debug an earlier forking crash).

您可能想要检查的是 pom 中 build/pluging/plugin 配置中surefire或failsafe的argline设置。我在那里有一些不正确的东西导致分叉的虚拟机失败(具有讽刺意味的是,我把 maven.failsafe.debug 放在那里来帮助调试早期的分叉崩溃)。

回答by palimpsestor

FWIW, I have experienced this error when the JVM ran out of memory during the maven build. On linux this was detected by OOM killer, which ended up generating kernel messages like Aug 28 20:53:27 ip-xxx-xxx-xxx-xxx kernel: [248686.775455] java invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0.

FWIW,当 JVM 在 maven 构建期间内存不足时,我遇到了这个错误。在 linux 上,这是由 OOM 杀手检测到的,它最终生成了像 Aug 28 20:53:27 ip-xxx-xxx-xxx-xxx kernel: [248686.775455] java invoked oom-killer: gfp_mask=0x201da, order=0, oom_score_adj=0.

I guess on a mac you'd just want to monitor your memory usage with ActivityMonitor.

我猜在 Mac 上,您只想使用 ActivityMonitor 监控内存使用情况。

回答by Chad Van De Hey

If anyone is including a custom argLine argument, you must reconsider because it is likely the source of your issues with the memory allocation.

如果有人包含自定义 argLine 参数,您必须重新考虑,因为它可能是您的内存分配问题的根源。

For Example (I used to have):

例如(我曾经有过):

<argLine>XX:MaxPermSize=4096m ${argLine}</argLine>

Now I use hard specified values:

现在我使用硬指定值:

<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>

For whatever reason, Applications that integrate with Surefire such as Jacoco, dont request enough memory to coexist with the testing that happens at build time.

无论出于何种原因,与 Surefire 集成的应用程序(例如 Jacoco)都不会请求足够的内存来与构建时发生的测试共存。

(more information can also be found at this s.o. question (1))

(更多信息也可以在这个问题(1)中找到)

(1)-maven jacoco: not generating code coverage report

(1)- maven jacoco:不生成代码覆盖率报告

回答by Aaron Digulla

JVM options that can help:

可以提供帮助的 JVM 选项:

-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=c:/dumps/

Note: You can use forward slashes.
Note 2: Make sure the folder exists and that the process has write permission. On recent windows systems, C:\is write protected.
Note 3: Make sure you have enough free space to write the dump. The Java 9 documentation mentions that the system's temp folder will be used when the disk is full.

注意:您可以使用正斜杠。
注意 2:确保文件夹存在并且进程具有写入权限。在最近的 Windows 系统上,C:\是写保护的。
注意 3:确保您有足够的可用空间来写入转储。Java 9 文档提到当磁盘已满时将使用系统的临时文件夹。

If there is no dump file, then you JVM didn't run out of memory.

如果没有转储文件,那么您的 JVM 没有耗尽内存。

The next option is -XX:ErrorFile=which allows to the JVM to log fatal errors.

下一个选项是-XX:ErrorFile=允许 JVM 记录致命错误。

-XX:+ShowMessageBoxOnErrorshows an error dialog if the JVM crashes.

-XX:+ShowMessageBoxOnError如果 JVM 崩溃,则显示错误对话框。

Note: You can change the flags of a running JVM using the jinfocommand.

注意:您可以使用该jinfo命令更改正在运行的 JVM 的标志。

Pass these options to Maven Surefire via the argLineoption:

通过以下选项将这些选项传递给 Maven Surefire argLine

<build>
    <plugins>
        <plugin>
            <artifactId>maven-surefire-plugin</artifactId>
            <configuration>
                <!-- -XX:HeapDumpPath=C:\ -XX:+ShowMessageBoxOnError  -->
                <argLine>@{argLine} -XX:+HeapDumpOnOutOfMemoryError -Xmx1g -XX:HeapDumpPath=H:/dumps/ -XX:ErrorFile=H:/dumps/ -XX:+ShowMessageBoxOnError</argLine>
            </configuration>
        </plugin>
    </plugins>
</build>

The strange @{argLine}at the beginning allows other plugins like Jacoco to inject their options. For this to work, you need to add an empty property:

@{argLine}开头的奇怪允许其他插件如 Jacoco 注入他们的选项。为此,您需要添加一个空属性:

<properties>
    <argLine></argLine> <!-- Fallback when Jacoco isn't active. -->
</properties>

You can verify that it works when the error happens: Maven will then dump the whole command line used to start the forked JVM.

您可以在发生错误时验证它是否有效:然后 Maven 将转储用于启动分叉 JVM 的整个命令行。

回答by capcom923

I just delete all the maven repository and run maven clean install. Then the issue is gone.

我只是删除所有 maven 存储库并运行 maven clean install。那么问题就没有了。

回答by flags

Changing the configuration of the plugin should resolve the problem:

更改插件的配置应该可以解决问题:

<project>
  [...]
  <build>
    <plugins>
      <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>3.0.0-M1</version>
        <configuration>
          <useSystemClassLoader>false</useSystemClassLoader>
        </configuration>
      </plugin>
    </plugins>
  </build>
  [...]
</project>

As suggested in this postand in the main documentationof the plugin.

正如这篇文章和插件的主要文档中所建议的那样。

回答by adminfd

In my case the configuration forkedProcessExitTimeoutInSeconds for the maven-surefire-plugin helps. The default value are since maven-surefire-plugin:2.20.1 30 seconds. My project gots very time consuming test and so the forked JVM chrashes. Configure the plugin in the pom with the following property solves the problem.

在我的情况下,maven-surefire-plugin 的配置 forkedProcessExitTimeoutInSeconds 有帮助。默认值是自 maven-surefire-plugin:2.20.1 30 秒。我的项目进行了非常耗时的测试,因此分叉的 JVM 崩溃了。使用以下属性在pom中配置插件解决了问题。

<plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <configuration>
                <forkedProcessExitTimeoutInSeconds>120</forkedProcessExitTimeoutInSeconds>
        </configuration>
</plugin>