Reputation: 1053
a Java application of mine is launching an external program using Runtime.exec(String[], String[], File). In general, this is working fine. However, I notice an important difference between Linux, and Windows. Suggest the following code snippet:
Process pr = Runtime.getRuntime(cmdArray, env, workDir);
startThreadProcessingStdout(pr.getInputStream());
startThreadProcessingStderr(pr.getErrorStream());
int status = pr.waitFor();
On Windows, my threads are done when waitFor() returns. (At least in the sense, that they have seen all required input.)
On Linux, however, the process is gone, but the threads are still busily reading input. I can fix that by changing my snippet as follows:
Process pr = Runtime.getRuntime(cmdArray, env, workDir);
AtomicBoolean outRunning = startThreadProcessingStdout(pr.getInputStream());
AtomicBoolean errRunning = startThreadProcessingStderr(pr.getErrorStream());
int status = pr.waitFor();
while (outRunning || errRunning) {
Thread.sleep(100);
}
However, that seems clumsy, and slow. Is there a better solution for my problem?
Upvotes: 2
Views: 206
Reputation: 111259
It sounds like the program you are running starts a background subprocess of its own, and this subprocess inherits the stdout and stderr file descriptors.
Process.waitFor
waits until this the parent process exits. When it does, it can leave the subprocess running. Since the subprocess inherited stdout and stderr, the pipes used to communicate with Java program remain open until the subprocess exits (or closes them through other means).
Upvotes: 1