私は、多くの依存関係と多くの単体テストがあるかなり複雑なJavaプロジェクトに取り組んでいます。
Mac(mavericks)でJava 1.6.0_65を使用し、maven 3.0.5でmaven-surefire-plugin:2.16をいくつかのフォークで実行しています。私の問題は、いくつかのフォークでこのセットアップを実行すると、フォークが次のように終了することです:
「フォークVMは適切にさよならを言わずに終了しました。VMクラッシュまたはSystem.exitが呼び出されましたか?」
1つのフォークのみでこれを実行しても、問題は発生しません(すべてが合格します)
このStackOverflowの質問 および この確実なバグ (これまでに解決されたようです)など、この問題に関する情報があります。
この状況に対する「回答」は、コードでSystem.exit()を呼び出すものを見つけることです-何も見つかりません。
または、JVMがクラッシュする原因-hs_pidクラッシュレポートはありません。
私の質問は、この原因を特定するためにどのような戦略を使用できますか?明確にするために、上記の回答には興味がありませんが、発信元を見つける方法。 (または、これが原因である可能性のあるものとはまったく別の答えが良い)
私の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>
#1を更新--debug(-X)でmavenゴールを実行した後、関連する出力を追加
[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.access$300(ForkStarter.Java:85)
at org.Apache.maven.plugin.surefire.booterclient.ForkStarter$2.call(ForkStarter.Java:288)
at org.Apache.maven.plugin.surefire.booterclient.ForkStarter$2.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
手順:
(1)-e
および-X
オプションを指定してmvnを実行し、デバッグ情報を取得します。
(2)出力で「エラー」を探します。私の場合、mvnコマンドを実行すると、出力の一部が含まれます。
[ERROR] Command wascmd.exe /X /C "C:\dev\dev-tools\.....
(3)問題のあるコマンドをコマンドシェルで直接実行します。
私の場合、実行
cmd.exe /X /C "C:\dev\dev-tools\....
コマンドラインからOutOfMemoryErrorが発生しました。
Maven Surefireのドキュメントに従って、分岐したVM in debug mode を実行できます。常に失敗する場合は、終了するまでコードをデバッグできます。
FWIW、mavenビルド中にJVMのメモリが不足したときにこのエラーが発生しました。 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
。
Macでは、ActivityMonitorでメモリ使用量を監視したいだけだと思います。
ここに、私がこの問題で立ち往生している他の人を助けるために使用した戦略を書いています。
System.exit()が呼び出されたときにSecurityManagerを利用して例外をスローすることができます。その後、スタックトレースを調べて、exit()を呼び出したユーザーを正確に確認できます。これは、独自のコードからではなく、依存しているjarファイルの1つに隠されたコードからexitの呼び出しが行われた場合に特に便利です。
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 ) ;
}
誰かがカスタムargLine引数を含めている場合、メモリ割り当ての問題の原因である可能性が高いため、再検討する必要があります。
例(私が持っていた):
<argLine>XX:MaxPermSize=4096m ${argLine}</argLine>
今、私はハード指定された値を使用します:
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
何らかの理由で、JacocoなどのSurefireと統合するアプリケーションは、ビルド時に発生するテストと共存するために十分なメモリを要求しません。
(詳細については、この質問(1)をご覧ください)
プラグインの構成を変更すると、問題が解決するはずです。
<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>
この post およびプラグインのメイン documentation で示唆されているように。
チェックしたいのは、pomのbuild/pluging/plugin configのsurefireまたはfailsafeのargline設定です。そこでフォークされたvmが失敗する原因となる不適切なものがありました(皮肉なことに、以前のフォーククラッシュのデバッグを支援するためにmaven.failsafe.debugを配置しました)。
すべてのmavenリポジトリーを削除して、maven clean installを実行します。その後、問題はなくなりました。
役立つJVMオプション:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=c:/dumps/
注:スラッシュを使用できます。
注2:フォルダーが存在し、プロセスに書き込み権限があることを確認してください。最近のWindowsシステムでは、C:\
は書き込み保護されています。
注3:ダンプを書き込むのに十分な空き領域があることを確認してください。 Java 9のドキュメントでは、ディスクがいっぱいになるとシステムのtempフォルダーが使用されることに言及しています。
ダンプファイルがない場合、JVMはメモリ不足になりませんでした。
次のオプションは-XX:ErrorFile=
これにより、JVMで致命的なエラーを記録できます。
-XX:+ShowMessageBoxOnError
は、JVMがクラッシュした場合にエラーダイアログを表示します。
注:jinfo
コマンドを使用して、実行中のJVMのフラグを変更できます。
argLine
オプションを介してこれらのオプションをMaven Surefireに渡します。
<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>
奇妙な@{argLine}
最初に、Jacocoのような他のプラグインがオプションを挿入できるようにします。これが機能するには、空のプロパティを追加する必要があります。
<properties>
<argLine></argLine> <!-- Fallback when Jacoco isn't active. -->
</properties>
エラーが発生したときに動作することを確認できます。Mavenは、分岐したJVMの起動に使用したコマンドライン全体をダンプします。
私の場合、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>