6
votes

Comment surveiller le processus externe couru par ProcessBuilder?

Cela devrait être plutôt simple, mais je ne vois rien d'utile dans javadocs .

Ce dont j'ai besoin, c'est d'exécuter un processus externe à partir de mon code Java, puis de pouvoir surveiller si ce processus a été arrêté ou non. En d'autres termes, je veux pouvoir déterminer de manière fiable si mon processus externe n'a pas été fini par l'utilisateur.

Si aucune solution de plate-forme croisée n'existe, je n'accepterai rien de travail sous Linux.

Mon extrait de code actuel: xxx


2 commentaires

Que voulez-vous dire "arrêt" versus "non terminé par l'utilisateur". Parlez-vous d'un code d'erreur ou d'une autre sortie?


Eh bien, disant «terminé par l'utilisateur» pourrait ne pas être aussi précis. Ce que je veux vraiment savoir, c'est si le processus fonctionne toujours à un moment donné.


3 Réponses :


5
votes

Je ne suis pas sûr que je comprends la question, mais une façon de le faire est d'appeler processus.exitvalue (); code>. Il jette une exception si le processus n'a pas encore terminé:

ProcessBuilder pb = new ProcessBuilder("/bin/sleep", "5");
Process process = pb.start();
// open accessability of the UNIXProcess.hasExited field using reflection
Field field = process.getClass().getDeclaredField("hasExited");
field.setAccessible(true);
// now we can get the field using reflection
while (!(Boolean) field.get(process)) {
    ...
}


3 commentaires

Pensé à cela, mais cela semble un peu comme l'API 'Abus'. J'aimerais savoir si le processus est en cours d'exécution, pas si la résiliation du processus n'a pas eu lieu. Je sais que ce devrait être le même, mais honnêtement, je m'attendais à une composante API qui prendrait une instance existante et pourrait fournir des métadonnées supplémentaires concernant l'état du fil exécutant dans ce processus.


@ Łukaszbachman Je ne considérerais pas que cela soit d'API "Abus" du tout. Tout ce qu'il est est la condition non booléenne. J'ai également ajouté un moyen d'accéder à la valeur interne hasexited , mais c'est un piratage qui utilise la réflexion.


Je vais aller avec waitfor () , mais +1 pour une idée de réflexion.



7
votes

Démarrer un nouveau fil qui appelle processus.waitfor () code> et définit un indicateur lorsque cet appel revient. Ensuite, vous pouvez vérifier que le drapeau à chaque fois que vous souhaitez voir si le processus est terminé.

public class ProcMon implements Runnable {

  private final Process _proc;
  private volatile boolean _complete;

  public boolean isComplete() { return _complete; }

  public void run() {
    _proc.waitFor();
    _complete = true;
  }

  public static ProcMon create(Process proc) {
    ProcMon procMon = new ProcMon(proc);
    Thread t = new Thread(procMon);
    t.start();
    return procMon;
  }
}


0 commentaires

2
votes

Sur la base de l'extrait de code spécifique de la question, je pourrais être utile d'ajouter que depuis 1.8 le processus de la classe a une méthode isalive () est disponible

Lien de documentation: HTTPS: // DOCS. oracle.com/javase/8/docs/api/java/lang/process.html

Bonne chance à quiconque lisant ça!


0 commentaires