Saturday, October 26, 2013

Solution: Java Runtime.exec hangs abnormally

background
i was debugging a J2EE project which has a method that invokes an external program.
in most scenario it just works fine, but i spotted some hanging external process after a period of full-load time.

problem
this is the code when things went wrong:
private void execute(String command) throws IOException {
        Runtime runTime = Runtime.getRuntime();
        LOG.info("executing: " + command);
        String[] args = new String[] {
            "/bin/sh", "-c", command
        };
        Process proc = runTime.exec(args);
        try {
            if (proc.waitFor() != 0) {
                throw new IOException("subprocess exited with non-zero code");
            }
        } catch (InterruptedException e) {
            throw new IOException("interrupted");

        }
}

analyzing
it turns out that there is a very long output (through stdout) in every hanging process.
It is documented here: http://docs.oracle.com/javase/6/docs/api/java/lang/Process.html
"Because some native platforms only provide limited buffer size for standard input and output streams, failure to promptly write the input stream or read the output stream of the subprocess may cause the subprocess to block, and even deadlock."
solution A
if output should be ignored, just append "> /dev/null" to command. and it should work fine.

solution B
if output is necessary, start reading stdin and stderr, instead of just waiting for subprocess to finish.

No comments:

Post a Comment