Est-il possible de tuer une machine virtuelle Java à partir d'une autre machine virtuelle?

StackOverflow https://stackoverflow.com/questions/63758

  •  09-06-2019
  •  | 
  •  

Question

J'ai une application Java qui lance une autre application java. Le lanceur a un minuteur de surveillance et reçoit des notifications périodiques du deuxième ordinateur virtuel. Toutefois, si aucune notification n’est reçue, la deuxième machine virtuelle doit être supprimée et le programme de lancement effectue certaines activités de nettoyage supplémentaires.

La question est la suivante: existe-t-il un moyen de le faire en utilisant uniquement Java? jusqu'à présent, je dois utiliser des méthodes natives pour effectuer cette opération et il est en quelque sorte moche.

Merci!

Était-ce utile?

La solution

Il se peut que quelque chose me manque, mais vous ne pouvez pas appeler le destroy () sur la méthode objet Process renvoyé par Runtime.exec () ?

Autres conseils

Vous pouvez utiliser java.lang.Process faire ce que vous voulez. Une fois que vous avez créé le processus imbriqué et que vous avez une référence à l'instance de processus, vous pouvez obtenir des références à ses flux de sortie et d'erreur standard. Vous pouvez régulièrement les surveiller et appeler .destroy () si vous souhaitez fermer le processus. Le tout pourrait ressembler à quelque chose comme ça:

Process nestedProcess = new ProcessBuilder("java mysubprocess").start();
InputStream nestedStdOut = nestedProcess.getInputStream(); //kinda backwards, I know
InputStream nestedStdErr = nestedProcess.getErrorStream();
while (true) {
    /*
       TODO: read from the std out or std err (or get notifications some other way)
       Then put the real "kill-me" logic here instead of if (false)
    */
    if (false) {
        nestedProcess.destroy();
        //perform post-destruction cleanup here
        return;
    }

    Thread.currentThread().sleep(1000L); //wait for a bit
}

J'espère que cela vous aidera,

Sean

Vous pouvez également publier un service (via burlap, hessian, etc.) sur la deuxième machine virtuelle Java qui appelle System.exit () et le consommer à partir de la machine virtuelle de surveillance. Si vous souhaitez uniquement arrêter la deuxième machine virtuelle Java lorsqu'elle cesse d'envoyer ces notifications périodiques, il se peut qu'elle ne soit pas en état de répondre à l'appel de service.

L'appel de commandes shell avec java.lang.Runtime.exec () est probablement votre meilleur choix.

La méthode habituelle consiste à appeler Process.destroy () ... mais il s’agit d’une solution incomplète, car lors de l’utilisation de la JVM Sun sur * nix, détruisez les mappes sur un SIGTERM, ce qui ne permet pas nécessairement de terminer le processus (par exemple. que vous avez également besoin de SIGKILL). Le résultat final est que vous ne pouvez pas gérer réellement les processus avec Java.

Il existe quelques bogues non résolus concernant ce problème, voir: texte du lien

java.lang.Process a une méthode waitFor () pour attendre la fin du processus et une méthode destroy () pour tuer le sous-processus.

OK, l'essentiel est le suivant:

J'utilisais l'API Process pour fermer la deuxième machine virtuelle, mais cela ne fonctionnerait pas.

La raison en est que ma deuxième application est une application Eclipse RCP et que je l'ai lancée à l'aide du programme de lancement eclipse.exe inclus.

Cependant, cela signifie que la méthode destroy () de l'API Process cible le processus eclipse.exe. Tuer ce processus laisse le processus Java indemne. Ainsi, un de mes collègues ici a écrit une petite application qui va tuer la bonne application.

Ainsi, l’une des solutions permettant d’utiliser l’API de processus (et de supprimer les étapes intermédiaires redondantes) consiste à sortir du lanceur Eclipse, la première machine virtuelle devant en dupliquer toutes les fonctionnalités.

Je suppose que je devrai me rendre au travail.

Vous devriez pouvoir faire java.lang.Runtime.exec et les commandes shell.

Vous pouvez faire en sorte que le code java détecte la plate-forme au moment de l'exécution et déclenche la commande kill process de la plate-forme. C’est vraiment un raffinement de votre solution actuelle.

Il existe également Processus .destroy () , si vous utilisez le API ProcessBuilder

Pas exactement la gestion des processus, mais vous pouvez démarrer un serveur rmi dans la machine virtuelle java que vous lancez et lier un remote avec une méthode qui effectue le nettoyage requis et appelle System.exit (). La première machine virtuelle peut ensuite appeler cette méthode distante pour arrêter la deuxième machine virtuelle.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top