org.biojava.utils.process
Class ExternalProcess

java.lang.Object
  extended by org.biojava.utils.process.ExternalProcess

public final class ExternalProcess
extends java.lang.Object

Utility class to execute an external process and to handle the STDOUT, STDERR and STDIN streams in multiple threads managed by a thread pool.

This class is intended for applications that call an external program many times, e.g. in a loop, and that need high performance throughput, i.e. the program's input and output should not be written to disk. The Java Runtime.exec(java.lang.String) methods requires the application to read/write the external program's input and output streams in multiple threads. Otherwise the calling application may block. However, instantiating multiple threads for each call is extensive. On Linux systems there is also the problem that each Java thread is represented by a single process and the number of processes is limited on Linux. Because the Java garbage collector does not free the Thread objects properly, an application might run out of threads (indicated by a OutOfMemoryError exception) after multiple iterations. Therefore, the ExternalProcess class uses a thread pool.

The simplest way to use this class is by calling the static methods execute(String) and execute(String, String, StringWriter, StringWriter). However, these methods are not thread safe and no configuration is possible. In the former case the program's input, output and error output is redirected to STDIN, STDOUT and STDERR of the calling program. In the latter case input is provided as string and output and error output is written to StringWriter objects. The environment, i.e. the current working directory and the environment variables, are inherited from the calling process. In both cases, a static thread pool of size THREAD_POOL_SIZE is used. The command that should be executed is provided as a string argument.

In scenarios where the environment has to be changed, the program input is generated just in time, or the program's output is parsed just in time, the use of an explicit instance of the ExternalProcess class is recommended. This instance could be initialized with a custom thread pool. Otherwise a SimpleThreadPool of size 3 is used. The input and output is managed by multithreaded input handler and output handler objects. There are four predefined handlers that read the program's input from a Reader object or a InputStream object and write the program's output to a Writer object or a OutputStream object. These classes are called: ReaderInputHandler, SimpleInputHandler, WriterOutputHandler and SimpleOutputHandler. If no handlers are specified the input and output is redirected to the standards streams of the calling process.

Before one of the methods execute() or execute(Properties) is called, the commands property should be set. One may include placeholders of the form %PARAM% within the commands. If a Properties object is passed to the execute(Properties) method, the placeholders are replaced by the particular property value. Therefore, the Properties object must contain a key named PARAM (case doesn't matter). The environment for calling the external program can be configured using the properties workingDirectory and environmentProperties.

Finally, the sleepTime property can be increased, in case the output handlers are not able to catch the whole program's output within the given time. The default value is SLEEP_TIME [in milliseconds].

Version:
$Revision: 1.2 $
Author:
Martin Szugat
See Also:
Process

Field Summary
static int SLEEP_TIME
          Number of milliseconds the execute method should pauses after the external process has finished the execution.
static int THREAD_POOL_SIZE
          Size of the thread pool for the static execute methods.
 
Constructor Summary
ExternalProcess()
          Initializes the external process.
ExternalProcess(ThreadPool threadPool)
          Initializes the external process.
 
Method Summary
 int execute()
          Executes the external process and waits for its termination.
 int execute(java.util.Properties variables)
          Executes the external process and waits for its termination.
static int execute(java.lang.String commands)
          Executes an external program.
static int execute(java.lang.String commands, java.lang.String inputString, java.io.StringWriter outputString, java.io.StringWriter errorString)
          Executes an external program.
protected  void finalize()
          
 java.lang.String getCommands()
          Gets the command line including the path or name of the external program and its command line arguments.
 java.lang.String[] getEnvironmentProperties()
          Gets environment variables for the external process.
 OutputHandler getErrorHandler()
          Gets the output error handler which is responsible for the standard error output of the external process.
 InputHandler getInputHandler()
          Gets the input handler which is responsible for the standard input of the external process.
 OutputHandler getOutputHandler()
          Gets the output handler which is responsible for the standard output of the external process.
 int getSleepTime()
          Gets the number of milliseconds the execute(Properties) method should pauses after the external process is terminated.
 java.io.File getWorkingDirectory()
          Gets the working directory for the external process.
static java.lang.String joinCommands(java.lang.Object[] commandList)
          Joins a command list to a single command string.
static void main(java.lang.String[] args)
          Runs an external program from the command line.
static java.lang.String resolveCommands(java.lang.String commands, java.util.Properties variables)
          Resolves the given command line by replacing all placeholder of the format %NAME% with the values from the given properties for the corresponding keys of the format NAME.
 void setCommands(java.lang.String commands)
          Sets the command line including the path or name of the external program and its command line arguments.
 void setEnvironmentProperties(java.lang.String[] environmentProperties)
          Sets environment variables for the external process.
 void setErrorHandler(OutputHandler errorHandler)
          Sets the output error handler which is responsible for the standard error output of the external process.
 void setInputHandler(InputHandler inputHandler)
          Sets the input handler which is responsible for the standard input of the external process.
 void setOutputHandler(OutputHandler outputHandler)
          Sets the output handler which is responsible for the standard output of the external process.
 void setSleepTime(int sleepTime)
          Sets the number of milliseconds the execute(Properties) method should pauses after the external process is terminated.
 void setWorkingDirectory(java.io.File workingDirectory)
          Sets the working directory for the external process.
 ThreadPool threadPool()
          Gets the thread pool which is used for the input and output handlers.
 
Methods inherited from class java.lang.Object
clone, equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

THREAD_POOL_SIZE

public static final int THREAD_POOL_SIZE
Size of the thread pool for the static execute methods.

See Also:
Constant Field Values

SLEEP_TIME

public static final int SLEEP_TIME
Number of milliseconds the execute method should pauses after the external process has finished the execution.

See Also:
Constant Field Values
Constructor Detail

ExternalProcess

public ExternalProcess()
Initializes the external process.


ExternalProcess

public ExternalProcess(ThreadPool threadPool)
Initializes the external process.

Parameters:
threadPool - a thread pool with at least three threads or null if the default thread pool should be used
Method Detail

main

public static void main(java.lang.String[] args)
Runs an external program from the command line. The external process inherits the environment variables and the current working directory from the parent process.

Parameters:
args - the path or the name of the external program and its command line arguments

resolveCommands

public static java.lang.String resolveCommands(java.lang.String commands,
                                               java.util.Properties variables)
                                        throws java.lang.NullPointerException
Resolves the given command line by replacing all placeholder of the format %NAME% with the values from the given properties for the corresponding keys of the format NAME.

Parameters:
commands - the given command line
variables - the placeholders or null if no resolvement should be performed
Returns:
the new command line
Throws:
java.lang.NullPointerException - if commands is null.

execute

public static int execute(java.lang.String commands)
                   throws java.io.IOException,
                          java.lang.InterruptedException,
                          java.lang.NullPointerException,
                          java.lang.SecurityException,
                          java.lang.IllegalArgumentException
Executes an external program. The working directory and the environment variables are inherited from the parent process. The program input is read from STDIN, the program output is written to STDOUT and the program error output is written to STDERR.

Note: This method is not thread-safe.

Parameters:
commands - the command line including the path or the name of the external program and its command line arguments
Returns:
the exit code from the external program
Throws:
java.lang.SecurityException - if a security manager exists and its checkExec method doesn't allow creation of a subprocess.
java.io.IOException - if an I/O error occurs.
java.lang.NullPointerException - if commands is null.
java.lang.IllegalArgumentException - if commandList is empty.
java.lang.InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown.

execute

public static int execute(java.lang.String commands,
                          java.lang.String inputString,
                          java.io.StringWriter outputString,
                          java.io.StringWriter errorString)
                   throws java.io.IOException,
                          java.lang.InterruptedException,
                          java.lang.NullPointerException,
                          java.lang.SecurityException,
                          java.lang.IllegalArgumentException
Executes an external program. The working directory and the environment variables are inherited from the parent process.

Note: This method is not thread-safe.

Parameters:
commands - the command line including the path or the name of the external program and its command line arguments
inputString - the input for the external programm or null if the input should be read from STDIN
outputString - the output of the external programm or null if the output should be written to STDOUT
errorString - the error output of the external program or null if the error output should be written to STDERR
Returns:
the exit code from the external program
Throws:
java.lang.SecurityException - if a security manager exists and its checkExec method doesn't allow creation of a subprocess.
java.io.IOException - if an I/O error occurs.
java.lang.NullPointerException - if commandList is null.
java.lang.IllegalArgumentException - if commandList is empty.
java.lang.InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown.

joinCommands

public static java.lang.String joinCommands(java.lang.Object[] commandList)
                                     throws java.lang.NullPointerException
Joins a command list to a single command string.

Parameters:
commandList - the list of the command and its arguments
Returns:
the joined command line
Throws:
java.lang.NullPointerException - if commandList is null.

execute

public int execute()
            throws java.io.IOException,
                   java.lang.InterruptedException,
                   java.lang.SecurityException,
                   java.lang.IllegalArgumentException
Executes the external process and waits for its termination.

Returns:
the exit code from the external process
Throws:
java.lang.IllegalArgumentException - if the command is empty
java.lang.SecurityException - if a security manager exists and its checkExec method doesn't allow creation of a subprocess.
java.io.IOException - if an I/O error occurs.
java.lang.InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown.

execute

public int execute(java.util.Properties variables)
            throws java.io.IOException,
                   java.lang.InterruptedException,
                   java.lang.SecurityException,
                   java.lang.IllegalArgumentException
Executes the external process and waits for its termination.

Parameters:
variables - a list of key-value-pairs that should be used to replace placeholders in the command line. May be null.
Returns:
the exit code from the external process
Throws:
java.lang.SecurityException - if a security manager exists and its checkExec method doesn't allow creation of a subprocess.
java.lang.IllegalArgumentException - if the command is empty
java.io.IOException - if an I/O error occurs.
java.lang.InterruptedException - if the current thread is interrupted by another thread while it is waiting, then the wait is ended and an InterruptedException is thrown.

getCommands

public java.lang.String getCommands()
Gets the command line including the path or name of the external program and its command line arguments.

Returns:
the command line

setCommands

public void setCommands(java.lang.String commands)
                 throws java.lang.NullPointerException
Sets the command line including the path or name of the external program and its command line arguments.

Parameters:
commands - the command line
Throws:
java.lang.NullPointerException - if commands is null.

getEnvironmentProperties

public java.lang.String[] getEnvironmentProperties()
Gets environment variables for the external process.

Returns:
a list of strings in the format name=value or null if the environment variables should be inherited from the parent process

setEnvironmentProperties

public void setEnvironmentProperties(java.lang.String[] environmentProperties)
Sets environment variables for the external process.

Parameters:
environmentProperties - a list of strings in the format name=value or null if the environment variables should be inherited from the parent process

getErrorHandler

public OutputHandler getErrorHandler()
Gets the output error handler which is responsible for the standard error output of the external process.

Returns:
the error output handler

setErrorHandler

public void setErrorHandler(OutputHandler errorHandler)
Sets the output error handler which is responsible for the standard error output of the external process.

Parameters:
errorHandler - the error output handler or null if the error output should be redirected to STDERR

getInputHandler

public InputHandler getInputHandler()
Gets the input handler which is responsible for the standard input of the external process.

Returns:
the input handler

setInputHandler

public void setInputHandler(InputHandler inputHandler)
Sets the input handler which is responsible for the standard input of the external process.

Parameters:
inputHandler - the input handler or null if the input should be read from STDIN

getOutputHandler

public OutputHandler getOutputHandler()
Gets the output handler which is responsible for the standard output of the external process.

Returns:
the output handler

setOutputHandler

public void setOutputHandler(OutputHandler outputHandler)
Sets the output handler which is responsible for the standard output of the external process.

Parameters:
outputHandler - the output handler or null if the output should be redirected to STDOUT

threadPool

public ThreadPool threadPool()
Gets the thread pool which is used for the input and output handlers.

Returns:
a thread pool with at least three threads

getWorkingDirectory

public java.io.File getWorkingDirectory()
Gets the working directory for the external process.

Returns:
the working directory or null if it should be inherited from the parent process

setWorkingDirectory

public void setWorkingDirectory(java.io.File workingDirectory)
Sets the working directory for the external process.

Parameters:
workingDirectory - the working directory or null if it should be inherited from the parent process

getSleepTime

public int getSleepTime()
Gets the number of milliseconds the execute(Properties) method should pauses after the external process is terminated. This gives the stream handlers the time to complete their work.

Returns:
time in milliseconds

setSleepTime

public void setSleepTime(int sleepTime)
                  throws java.lang.IllegalArgumentException
Sets the number of milliseconds the execute(Properties) method should pauses after the external process is terminated. Increase this value if the output handlers didn't catch the whole program output.

Parameters:
sleepTime - time in milliseconds
Throws:
java.lang.IllegalArgumentException - if sleepTime is negative.

finalize

protected void finalize()

Overrides:
finalize in class java.lang.Object