How to monitor external process ran by ProcessBuilder?

11,670

Solution 1

Start a new Thread which calls Process.waitFor() and sets a flag when that call returns. then, you can check that flag whenever you want to see if the process has completed.

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;
  }
}

(some boilerplate omitted).

Solution 2

I'm not sure I'm understanding the question but one way to do this is to call process.exitValue();. It throws an exception if process has not yet terminated:

/**
 * Returns the exit value for the subprocess.
 *
 * @return  the exit value of the subprocess represented by this 
 *          <code>Process</code> object. by convention, the value 
 *          <code>0</code> indicates normal termination.
 * @exception  IllegalThreadStateException  if the subprocess represented 
 *             by this <code>Process</code> object has not yet terminated.
 */
abstract public int exitValue();

If you don't mind a hack, you can do something like the following if you are working on a ~Unix system which uses the UNIXProcess class. This does use reflection however:

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)) {
    ...
}

Solution 3

Based on the question's specific code snippet I might be useful to add that since 1.8 the Process class has an isAlive() method is available

Documentation link: https://docs.oracle.com/javase/8/docs/api/java/lang/Process.html

good luck to anyone reading this!

Share:
11,670
ŁukaszBachman
Author by

ŁukaszBachman

Humble Java developer.

Updated on June 13, 2022

Comments

  • ŁukaszBachman
    ŁukaszBachman almost 2 years

    This should be rather simple, but I don't see anything helpful in JavaDocs.

    What I need is to run some external process from my Java code and then be able to monitor if this process has been shutdown or not. In other words, I want to be able to reliably determine whether or not my external process was not ended by user.

    If no cross platform solution exists, I will accept anything working under Linux.

    My current snippet of code:

    public static void main(String[] args) {
        ProcessBuilder pb = new ProcessBuilder("some proces name");
    
        try {
            Process p = pb.start();
            // p.isRunning(); <- now, that would be helpful :-)
        } catch (IOException e) {
            e.printStackTrace();
        }
    }