private static int runSyncProcess ( boolean isVerbose , boolean isInheritIO , String [ ] cmdline , StringBuilder outputBuilder , File workingDirectory , Map < String , String > envs ) { final StringBuilder builder = outputBuilder == null ? new StringBuilder ( ) : outputBuilder ; // Log the command for debugging LOG . log ( Level . FINE , "Running synced process: ``{0}''''" , joinString ( cmdline ) ) ; ProcessBuilder pb = getProcessBuilder ( isInheritIO , cmdline , workingDirectory , envs ) ; /* combine input stream and error stream into stderr because 1. this preserves order of process's stdout/stderr message 2. there is no need to distinguish stderr from stdout 3. follow one basic pattern of the design of Python<~>Java I/O redirection: stdout contains useful messages Java program needs to propagate back, stderr contains all other information */ pb . redirectErrorStream ( true ) ; Process process ; try { process = pb . start ( ) ; } catch ( IOException e ) { LOG . log ( Level . SEVERE , "Failed to run synced process" , e ) ; return - 1 ; } // Launching threads to consume combined stdout and stderr before "waitFor". // Otherwise, output from the "process" can exhaust the available buffer for the combined stream // because stream is not read while waiting for the process to complete. // If buffer becomes full, it can block the "process" as well, // preventing all progress for both the "process" and the current thread. Thread outputsThread = createAsyncStreamThread ( process . getInputStream ( ) , builder , isVerbose ) ; try { outputsThread . start ( ) ; int exitValue = process . waitFor ( ) ; outputsThread . join ( ) ; return exitValue ; } catch ( InterruptedException e ) { // The current thread is interrupted, so try to interrupt reading threads and kill // the process to return quickly. outputsThread . interrupt ( ) ; process . destroy ( ) ; LOG . log ( Level . SEVERE , "Running synced process was interrupted" , e ) ; // Reset the interrupt status to allow other codes noticing it. Thread . currentThread ( ) . interrupt ( ) ; return - 1 ; } }
run sync process