Here\'s my scenario:
I just encountered the same problem. I think I have a workaround to the problem. In process A, I have the following code fragment after Process.waitFor(), where outT and errT are the threads to read process B's stdout and stderr, respectively:
try {
outT.join(1000);
if (outT.isAlive()) {
errmsg("stdout reader still alive, interrupting", null);
outT.interrupt();
}
} catch (Exception e) {
errmsg("Exception caught from out stream reader: "+e, e);
}
try {
errT.join(1000);
if (errT.isAlive()) {
errmsg("stderr reader still alive, interrupting", null);
errT.interrupt();
}
} catch (Exception e) {
errmsg("Exception caught from err stream reader: "+e, e);
}
p.destroy();
Not sure if p.destroy() is needed, but I have been trying all kinds of combinations to deal with the problem.
Anyway, in the run() method of the outT/errT threads, I have the following, where the 'pipe' variable is a Writer instance I am capturing stdout/stderr of the sub-process to. The 'in' variable is the stdout, or stderr, stream obtained from Process:
try {
r = new BufferedReader(new InputStreamReader(in, enc));
String line;
while (true) {
if (Thread.currentThread().isInterrupted()) {
errmsg("Text stream reader interrupted", null);
break;
}
if (r.ready()) {
line = r.readLine();
if (line == null) {
break;
}
pipe.write(line);
pipe.write(SystemUtil.EOL);
if (autoFlush) {
pipe.flush();
}
}
}
pipe.flush();
} catch (Throwable t) {
errmsg("Exception caught: "+t, t);
try { pipe.flush(); } catch (Exception noop) {}
} finally {
IOUtil.closeQuietly(in);
IOUtil.closeQuietly(r);
}
It seems that I never get an EOF indication from any sub-process, even after the sub-process terminates, hence, all the chicanery above to prevent stale threads and blocking.