public void run ( ) throws IOException { if ( this . isStarted ( ) || this . isComplete ( ) ) { throw new IllegalStateException ( "The process can only be used once." ) ; } final ProcessBuilder builder = new ProcessBuilder ( this . cmd ) ; builder . directory ( new File ( this . workingDir ) ) ; builder . environment ( ) . putAll ( this . env ) ; builder . redirectErrorStream ( true ) ; this . process = builder . start ( ) ; try { this . processId = processId ( this . process ) ; if ( this . processId == 0 ) { this . logger . debug ( "Spawned thread with unknown process id" ) ; } else { this . logger . debug ( "Spawned thread with process id " + this . processId ) ; } this . startupLatch . countDown ( ) ; final LogGobbler outputGobbler = new LogGobbler ( new InputStreamReader ( this . process . getInputStream ( ) , StandardCharsets . UTF_8 ) , this . logger , Level . INFO , 30 ) ; final LogGobbler errorGobbler = new LogGobbler ( new InputStreamReader ( this . process . getErrorStream ( ) , StandardCharsets . UTF_8 ) , this . logger , Level . ERROR , 30 ) ; outputGobbler . start ( ) ; errorGobbler . start ( ) ; int exitCode = - 1 ; try { exitCode = this . process . waitFor ( ) ; } catch ( final InterruptedException e ) { this . logger . info ( "Process interrupted. Exit code is " + exitCode , e ) ; } this . completeLatch . countDown ( ) ; // try to wait for everything to get logged out before exiting outputGobbler . awaitCompletion ( 5000 ) ; errorGobbler . awaitCompletion ( 5000 ) ; if ( exitCode != 0 ) { throw new ProcessFailureException ( exitCode ) ; } } finally { IOUtils . closeQuietly ( this . process . getInputStream ( ) ) ; IOUtils . closeQuietly ( this . process . getOutputStream ( ) ) ; IOUtils . closeQuietly ( this . process . getErrorStream ( ) ) ; } }
Execute this process blocking until it has completed .