In java determine if a process created using Runti

2019-02-18 09:14发布

问题:

Runtime.getRuntime.exex("abc.exe -parameters");

using .waitFor() does not help to determine the completion of process.

回答1:

Process.waitFor() should work. If it doesn't work then either:

  • there's a bug in the JVM (highly unlikely for something like this), or

  • there is something about the process and/or your Java code that means that the process won't exit.

The most likely reasons that a process launched from Java won't / can't exit are:

  • the process is blocked waiting for your Java application to give it some input,

  • the process is blocked waiting for your Java application to read its output,

  • it is blocked waiting on some external event; e.g. if it is trying to talk remote server that is not responding.

  • someone has sent it a STOP signal, or

  • it is just taking a looong time to run.

The first two of these reasons / causes can be addressed by (respectively) closing the Java output stream connected to its standard input, and reading (and possibly discarding) the Java input streams connected to its standard output and standard error. The other causes are intractable, and your only options are to wait it out or attempt to kill off the process if it takes too long.


Bottom line - find out why your process isn't completing. The blocked Process.waitFor() is the symptom, not the disease.



回答2:

Looks like JDK8 introduces Process.isAlive(). Surprised it took so long...

In the meantime, the best option seems to be to poll Process.exitValue(), wrapped in a try-catch:

// somewhere previous...
String[] cmd = { "abc.exe", "-p1", "-p2" };
Process process = Runtime.getRuntime.exec(cmd);

// call this method repeatedly until it returns true
private boolean processIsTerminated () {
    try {
        process.exitValue();
    } catch (IllegalThreadStateException itse) {
        return false;
    }
    return true;
}

Alternately, a similar method could return the exit value if the process had terminated, or some other specified value if not.



回答3:

I have a similar issue and neither of the methods written here works for me. This is my code:

public void startCCleaner() {
    System.out.println("Starting ccleaner...");
    try {
        Process process = new ProcessBuilder("C:\\Program Files\\CCleaner\\CCleaner64.exe").start();
        if(process.waitFor() == 0 ){
            System.out.println("Process terminated ");
        }
    } catch (IOException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}


回答4:

If you don't want to use waitFor(), which apparently you don't you can always test the exit value directly.

import java.util.*;
import java.io.*;
public class ProcExitTest
{
    public static void main(String args[])
    {
        try
        {            
            Runtime rt = Runtime.getRuntime();
            Process proc = rt.exec("<....>");
            int exitVal = proc.exitValue();
            System.out.println("Process exitValue: " + exitVal);
        } 
          catch (InterruptedException ie)
          {
            ie.printStackTrace();
          }
    }
}

exit code 0 means normal termination.