org.mbari.siam.utils
Class ProcessRunner

java.lang.Object
  extended by java.lang.Thread
      extended by org.mbari.siam.utils.ProcessRunner
All Implemented Interfaces:
java.lang.Runnable

public class ProcessRunner
extends java.lang.Thread

ProcessRunner provides a wrapper around the Java Runtime.getRuntime().exec() methods.

The problem with Runtime.exec() is that the created Process does not have its own terminal or console. All standard I/O is read/written to the streams created with the Process, which by default have no readers or writers. This is in contrast with how Linux shells (bash etc) deal with stdio -- the child process inherits the controlling terminal.

As a result, if you Runtime.exec() to a shell script, and that shell script does any I/O, it will hang after filling the output buffer.

ProcessRunner provides an intermediary "supervisor" thread between the calling thread and the exec'd Process, which dumps the Process's stdout and stderr to System.out and System.err. This simulates having a terminal attached for output, and prevents the exec'd Process from hanging due to filling up its output buffer.

ProcessRunner also provides an addCallback() method, to allow the caller to receive a callback when the child process finishes.

Note that this class doesn't resolve the input problem (this could be done, but this implementation doesn't do it). As a result, the scripts and/or programs handed to ProcessRunner should never try to read console input.

Also note that this class currently only implements two flavors of Runtime.exec(): String and String[].


Nested Class Summary
 
Nested classes/interfaces inherited from class java.lang.Thread
java.lang.Thread.State, java.lang.Thread.UncaughtExceptionHandler
 
Field Summary
 
Fields inherited from class java.lang.Thread
MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY
 
Constructor Summary
ProcessRunner(java.lang.String command)
          Constructor emulates the Runtime.exec(String) method
ProcessRunner(java.lang.String[] cmdarray)
          Constructor emulates the Runtime.exec(String[]) method
 
Method Summary
 void addCallback(ProcessRunnerCallback listener)
          Add a Callback.
 void destroyProcess()
          Executes Process.destroy()
 int exitValue()
          Returns Process.exitValue()
 java.lang.String getOutputString()
          Returns the output that the Process had sent to stdout and stderr, as a String.
 boolean isRunning()
          Similar to Thread.isAlive(), but returns true if wrapped Process is still running
static void main(java.lang.String[] args)
           
 void run()
          Run method just pipes Process's stdout to System.out and stderr to System.err.
protected  void runIt()
          Protected method actually runs the command, throws IOException
 int waitFor()
          Returns Process.waitFor()
 int waitFor(long timeout)
          Returns Process.waitFor()
 
Methods inherited from class java.lang.Thread
activeCount, checkAccess, clone, countStackFrames, currentThread, destroy, dumpStack, enumerate, getAllStackTraces, getContextClassLoader, getDefaultUncaughtExceptionHandler, getId, getName, getPriority, getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler, holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted, join, join, join, resume, setContextClassLoader, setDaemon, setDefaultUncaughtExceptionHandler, setName, setPriority, setUncaughtExceptionHandler, sleep, sleep, start, stop, stop, suspend, toString, yield
 
Methods inherited from class java.lang.Object
equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Constructor Detail

ProcessRunner

public ProcessRunner(java.lang.String command)
              throws java.io.IOException
Constructor emulates the Runtime.exec(String) method

Throws:
java.io.IOException

ProcessRunner

public ProcessRunner(java.lang.String[] cmdarray)
              throws java.io.IOException
Constructor emulates the Runtime.exec(String[]) method

Throws:
java.io.IOException
Method Detail

isRunning

public boolean isRunning()
Similar to Thread.isAlive(), but returns true if wrapped Process is still running


addCallback

public void addCallback(ProcessRunnerCallback listener)
Add a Callback.


runIt

protected void runIt()
              throws java.io.IOException
Protected method actually runs the command, throws IOException

Throws:
java.io.IOException

run

public void run()
Run method just pipes Process's stdout to System.out and stderr to System.err. Exits when Process is no longer running

Specified by:
run in interface java.lang.Runnable
Overrides:
run in class java.lang.Thread

exitValue

public int exitValue()
              throws java.lang.IllegalThreadStateException
Returns Process.exitValue()

Throws:
java.lang.IllegalThreadStateException

waitFor

public int waitFor()
            throws java.lang.InterruptedException
Returns Process.waitFor()

Throws:
java.lang.InterruptedException

waitFor

public int waitFor(long timeout)
            throws java.lang.InterruptedException,
                   java.lang.IllegalThreadStateException
Returns Process.waitFor()

Parameters:
timeout - Timeout to wait in milliseconds
Throws:
java.lang.InterruptedException
java.lang.IllegalThreadStateException

destroyProcess

public void destroyProcess()
Executes Process.destroy()


getOutputString

public java.lang.String getOutputString()
Returns the output that the Process had sent to stdout and stderr, as a String. The normal sequence of calls is exec(), waitFor(), and then getOutputString(). That is, it doesn't make much sense to call getOutputString() until after the call has completed; though it's not illegal to call it sooner.


main

public static void main(java.lang.String[] args)
                 throws java.io.IOException
Throws:
java.io.IOException


Copyright © 2003 MBARI.

The Monterey Bay Aquarium Research Institute (MBARI) provides this documentation and code "as is", with no warranty, express or implied, of its quality or consistency. It is provided without support and without obligation on the part of MBARI to assist in its use, correction, modification, or enhancement.