Je travaille sur un projet Java plutôt complexe comportant de nombreuses dépendances et de nombreux tests unitaires.
J'utilise Java 1.6.0_65 sur mac (non-conformistes) avec maven 3.0.5 avec maven-surefire-plugin: 2.16 fonctionnant sur plusieurs forks. Mon problème est que l'exécution de cette configuration avec plusieurs fourches provoque la fermeture d'une fourche avec:
"Le fork VM s'est terminé sans dire au revoir correctement. VM plant ou System.exit appelé?"
exécuter ceci avec un seul fork ne produit pas le problème (et tout passe)
Il y a quelques informations là-bas sur ce problème, y compris cette question de StackOverflow et ce bogue infâme (qui semble être résolu à ce jour)
Je suis conscient que la "réponse" à cette situation est de trouver ce que dans mon code appelle System.exit () - Rien que je pourrais trouver.
Ou ce qui provoque le blocage de ma machine virtuelle Java - il n'y a pas de rapport de crash hs_pid.
Ma question est quel type de stratégie puis-je utiliser pour trouver cette cause? .__ Pour clarifier, la réponse ci-dessus ne m'intéresse pas, mais un moyen de trouver d'où elle vient. (Ou mieux encore, une réponse totalement différente à ce qui pourrait en être la cause)
ma configuration Surefire est: (mais j'ai essayé d'autres combinaisons)
<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>
Mise à jour n ° 1 Ajout de la sortie pertinente après avoir exécuté l'objectif maven avec --debug (-X)
[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
Pas:
(1) Exécutez mvn avec les options -e
et -X
pour obtenir plus d’informations de débogage.
(2) Recherchez "Erreur" dans la sortie. Dans mon cas, lorsque j'ai exécuté la commande mvn, une partie de la sortie incluait:
[ERROR] Command wascmd.exe /X /C "C:\dev\dev-tools\.....
(3) Exécutez la commande problématique directement dans la commande Shell.
Dans mon cas, exécuter
cmd.exe /X /C "C:\dev\dev-tools\....
à partir de la ligne de commande a entraîné une erreur OutOfMemoryError.
FWIW, j'ai rencontré cette erreur lorsque la machine virtuelle Java a manqué de mémoire lors de la création de Maven. Sur Linux, cela a été détecté par le tueur OOM, qui a fini par générer des messages du noyau tels que 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
.
Je suppose que sur un Mac, vous souhaitez simplement surveiller votre utilisation de la mémoire avec ActivityMonitor.
Après la documentation Maven Surefire, vous pouvez exécuter le fichier VM créé en mode debug , s'il échoue toujours. Vous pouvez ensuite déboguer votre code jusqu'à sa sortie.
Si quelqu'un inclut un argument argLine personnalisé, vous devez le reconsidérer car il est probablement à l'origine de vos problèmes d'allocation de mémoire.
Par exemple (j'avais l'habitude d'avoir):
<argLine>XX:MaxPermSize=4096m ${argLine}</argLine>
Maintenant, j'utilise des valeurs précises spécifiées:
<argLine>-Xmx1024m -XX:MaxPermSize=256m</argLine>
Pour une raison quelconque, les applications qui s’intègrent à Surefire, telles que Jacoco, ne demandent pas assez de mémoire pour coexister avec les tests qui ont lieu au moment de la construction.
(Plus d'informations peuvent également être trouvées à cette question s.o. (1))
(1) - maven jacoco: ne pas générer de rapport de couverture de code
Nous écrivons ici la stratégie que j’avais pour aider d’autres personnes aux prises avec ce problème.
Il est possible d'utiliser SecurityManager pour générer une exception lorsque System.exit () est appelé. vous pouvez ensuite examiner la trace de la pile pour voir exactement qui a appelé exit (). Ceci est particulièrement utile si l'appel à quitter a été effectué à partir d'un code caché à l'intérieur d'un des pots dont vous dépendez et non à partir de votre propre code.
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 ) ;
}
Changer la configuration du plugin devrait résoudre le problème:
<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>
Comme suggéré dans ce post et dans le documentation principal du plugin.
Ce que vous voudrez peut-être vérifier, c’est le paramètre argline pour le surfire ou le fail-safe dans les configurations build/pluging/plugin de votre pom. J'ai eu quelque chose d'incorrect qui a causé l'échec de la vm forkée (paradoxalement, j'ai mis maven.failsafe.debug ici pour aider à déboguer un plantage antérieur de la fourche).
Je viens de supprimer tout le référentiel Maven et d'exécuter maven clean install. Alors le problème est parti.
Options JVM pouvant vous aider:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=c:/dumps/
Remarque: vous pouvez utiliser des barres obliques.
Remarque 2: Assurez-vous que le dossier existe et que le processus dispose des droits en écriture. Sur les systèmes Windows récents, C:\
est protégé en écriture.
Note 3: Assurez-vous de disposer de suffisamment d’espace libre pour écrire le cliché. La documentation Java 9 indique que le dossier temporaire du système sera utilisé lorsque le disque est plein.
S'il n'y a pas de fichier de vidage, votre machine virtuelle Java ne manque pas de mémoire.
L'option suivante est -XX:ErrorFile=
, ce qui permet à la machine virtuelle Java de consigner les erreurs fatales.
-XX:+ShowMessageBoxOnError
affiche une boîte de dialogue d'erreur si la machine virtuelle Java se bloque.
Remarque: Vous pouvez modifier les indicateurs d'une machine virtuelle Java en cours d'exécution à l'aide de la commande jinfo
.
Transmettez ces options à Maven Surefire via l’option 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>
Le @{argLine}
étrange au début permet à d’autres plugins comme Jacoco d’injecter leurs options. Pour que cela fonctionne, vous devez ajouter une propriété vide:
<properties>
<argLine></argLine> <!-- Fallback when Jacoco isn't active. -->
</properties>
Vous pouvez vérifier que cela fonctionne lorsque l'erreur se produit: Maven va ensuite vider toute la ligne de commande utilisée pour démarrer la machine virtuelle Java créée.