HOWTO Use the ProcessTool Utility to Execute Binaries

What does ProcessTool do?

ProcessTool provides an interface for executing binary programs found on your server from within your Java application. It captures stdout and stderr into StringBuffers at the same time using separate threads.

Example capturing to two StringBuffers

    StringBuffer stdout = new StringBuffer();
    StringBuffer stderr = new StringBuffer();
    String[] cmd = {"java", "-help"};
    ProcessTool.exec(cmd, stdout, stderr);
    String str = stdout.toString() + stderr.toString();

Example using an OutputStream for stdout and a StringBuffer for stderr.

	ByteArrayOutputStream baos = new ByteArrayOutputStream();
    StringBuffer stderr = new StringBuffer();
    String cmd = "java -help";
    ProcessTool.exec(cmd, baos, stderr);
    String str = baos.toString("UTF-8") + stderr.toString();

Why not just use the "Process" Object provided by Java?

There's nothing wrong with the Java "Process" object-- in fact, ProcessTool wraps that object. Its value add is in automatically spawning a background thread to capture stderr to prevent the possibility of deadlock due to a single threaded process waiting for your app to read from stderr.

A key to understanding the risk is understanding that there is a buffer for each stream that could vary in size depending on configuration of the OS, but frequently consists of eight 512 byte blocks. A process can write to stdout or stderr without another process reading from it until either buffer is full. At that point, it will stop and wait for the next block to become available before it can continue writing. If you're reading from both places at once, it's not a problem. If you're only reading from stdin with plans to read from stderr later, you'll encounter deadlock if the stderr buffer fills up without being read.