ProcessBuilder: Forwarding stdout and stderr of started processes without blocking the main thread

I’m building a process in Java using ProcessBuilder as follows:

ProcessBuilder pb = new ProcessBuilder()
        .command("somecommand", "arg1", "arg2")
Process p = pb.start();

InputStream stdOut = p.getInputStream();

Now my problem is the following: I would like to capture whatever is going through stdout and/or stderr of that process and redirect it to System.out asynchronously. I want the process and its output redirection to run in the background. So far, the only way I’ve found to do this is to manually spawn a new thread that will continuously read from stdOut and then call the appropriate write() method of System.out.

new Thread(new Runnable(){
    public void run(){
        byte[] buffer = new byte[8192];
        int len = -1;
        while((len = > 0){
            System.out.write(buffer, 0, len);

While that approach kind of works, it feels a bit dirty. And on top of that, it gives me one more thread to manage and terminate correctly. Is there any better way to do this?


To only way in Java 6 or earlier is with a so called StreamGobbler (which you are started to create):

StreamGobbler errorGobbler = new StreamGobbler(p.getErrorStream(), "ERROR");

// any output?
StreamGobbler outputGobbler = new StreamGobbler(p.getInputStream(), "OUTPUT");

// start gobblers

private class StreamGobbler extends Thread {
    InputStream is;
    String type;

    private StreamGobbler(InputStream is, String type) { = is;
        this.type = type;

    public void run() {
        try {
            InputStreamReader isr = new InputStreamReader(is);
            BufferedReader br = new BufferedReader(isr);
            String line = null;
            while ((line = br.readLine()) != null)
                System.out.println(type + "> " + line);
        catch (IOException ioe) {

For Java 7, see Evgeniy Dorofeev’s answer.

Leave a Reply

Your email address will not be published. Required fields are marked *