Class ExternalProcess

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

public final class ExternalProcess extends 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$
Author:
Martin Szugat
See Also:
  • Field Details

    • THREAD_POOL_SIZE

      public static final int THREAD_POOL_SIZE
      Size of the thread pool for the static execute methods.
      See Also:
    • 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:
  • Constructor Details

    • 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 Details

    • main

      public static void main(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 String resolveCommands(String commands, Properties variables) throws 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:
      NullPointerException - if commands is null.
    • execute

      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:
      SecurityException - if a security manager exists and its checkExec method doesn't allow creation of a subprocess.
      IOException - if an I/O error occurs.
      NullPointerException - if commands is null.
      IllegalArgumentException - if commandList is empty.
      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(String commands, String inputString, StringWriter outputString, StringWriter errorString) throws IOException, InterruptedException, NullPointerException, SecurityException, 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:
      SecurityException - if a security manager exists and its checkExec method doesn't allow creation of a subprocess.
      IOException - if an I/O error occurs.
      NullPointerException - if commandList is null.
      IllegalArgumentException - if commandList is empty.
      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 String joinCommands(Object[] commandList) throws 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:
      NullPointerException - if commandList is null.
    • execute

      Executes the external process and waits for its termination.
      Returns:
      the exit code from the external process
      Throws:
      IllegalArgumentException - if the command is empty
      SecurityException - if a security manager exists and its checkExec method doesn't allow creation of a subprocess.
      IOException - if an I/O error occurs.
      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

      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:
      SecurityException - if a security manager exists and its checkExec method doesn't allow creation of a subprocess.
      IllegalArgumentException - if the command is empty
      IOException - if an I/O error occurs.
      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 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(String commands) throws 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:
      NullPointerException - if commands is null.
    • 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(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

      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

      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

      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

      Gets the thread pool which is used for the input and output handlers.
      Returns:
      a thread pool with at least three threads
    • 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(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 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:
      IllegalArgumentException - if sleepTime is negative.
    • finalize

      protected void finalize()
      Overrides:
      finalize in class Object