Ghostkeeper
Ghostkeeper

Reputation: 3050

Runtime.getRuntime().exec(...) causes deadlock

We're trying to call an external program in Windows using Runtime.getRuntime().exec(...), but it seems to cause a deadlock. The external process is started asynchronously, but after a short while stops doing anything. When I stop the Java thread, the external process continues, so it must somehow be waiting for the Java thread. This is our relevant code at the moment:

try {
    Process process = Runtime.getRuntime().exec(System.getProperty("user.dir") + "program.exe");
    BufferedReader input = new BufferedReader(new InputStreamReader(process.getInputStream())); //Read output of program from its buffer.
    String line;
    while((line = input.readLine()) != null) {
        System.out.println(line);
    }
    process.waitFor();
} catch(IOException e) {
    e.printStackTrace();
} catch(InterruptedException e) {
    e.printStackTrace();
}

The program stops after having output 3313 bytes. We tried various methods of emptying the buffer, since that seems to sometimes cause this problem.

The Java program is waiting for the external program to complete (process.waitFor()), and the external program doesn't complete until I terminate the Java program, hence causing a deadlock. How can we prevent this? We have no access to the source of the external program.

Upvotes: 3

Views: 1462

Answers (2)

Ghostkeeper
Ghostkeeper

Reputation: 3050

Finally found the culprit. Apparently, the runtime process not only provides an input stream (Process#getInputStream), but also an error stream (Process#getErrorStream). The error stream was filling up as well, since the external program gave some errors about files being in the wrong format.

The solution consisted of making a new runnable class that reads from a stream in a separate thread. The the main thread would then create two instances of this object, one that will read from the input stream and the other from the error stream, then let both instances run their thread asynchronously. This way both streams were being read at the same time, and the main thread would call Process#waitFor.

I hope this helps someone who stumbles on this problem as well.

Upvotes: 1

Masudul
Masudul

Reputation: 21961

The Java program is waiting for the external program to complete (process.waitFor()), and the external program doesn't complete until I terminate the Java program, hence causing a deadlock. How can we prevent this?

You can't prevent it. According to Java docs

If the subprocess has not yet terminated, the calling thread will be blocked until the subprocess exits.

Upvotes: 0

Related Questions