Although that code tries to read from both the output stream and the error stream, it's still prone to deadlock. If the process outputs a lot to its error stream, and the error stream buffers become full, your code is still trying to read from the output stream. However, there's nothing coming to that because the process is blocked on its error stream, which you're not consuming yet. It also won't end because the process doesn't end.
There are two solutions:
1) Do the reads in two threads, one for the output and one for the input. This is what
When Runtime.exec() won't teaches us. Be careful about interleaving the two though.
2) Use ProcessBuilder and call
redirectErrorStream(true). You'll then only need to read from the process' output stream.
I prefer the latter, because it lets the JVM and/or OS deal with merging the two streams.