Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Subprocess started from Java finishes using waitFor but streams aren't terminated

I am using Java's ProcessBuilder to start a subprocess, which is another Java program that has to run in a separate JVM.

I start two Threads to read from the stdout and stderr streams from the Process, so that there is no hang if the stream buffers are full. The call to Process.waitFor returns but the streams aren't terminated.

The code I am using looks something like (command is a list of strings):

ProcessBuilder pb = new ProcessBuilder(command);

final Process p = pb.start();
final ByteArrayOutputStream outStream = new ByteArrayOutputStream();
final ByteArrayOutputStream errStream = new ByteArrayOutputStream();

Thread outputThread = new Thread() {
    @Override
    public void run() {
        try {
            IOUtils.copy(p.getInputStream(), outStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    };
};
outputThread.start();

Thread errorThread = new Thread() {
    @Override
    public void run() {
        try {
            IOUtils.copy(p.getErrorStream(), errStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    };
};
errorThread.start();

int returncode = p.waitFor();
outputThread.join();
errorThread.join();

If I run something else, such as "java -version" or "dir" or something, the code works fine. I have access to the Java code that I am trying to run, but I have never heard that you should call close() on System.out.

like image 708
David Göransson Avatar asked Sep 19 '11 14:09

David Göransson


1 Answers

Apache commons exec does all this for you. A lot more easier to do...

http://commons.apache.org/exec/

like image 101
sethu Avatar answered Oct 02 '22 18:10

sethu