private void runCommand() throws IOException {
        ProcessBuilder builder = new ProcessBuilder(getExecString());
        Timer timeOutTimer = null;
        ShellTimeoutTimerTask timeoutTimerTask;
        timedOut = new AtomicBoolean(false);
        completed = new AtomicBoolean(false);

        if (environment != null) {
            builder.environment().putAll(this.environment);
        }
        if (dir != null) {
            builder.directory(this.dir);
        }

        builder.redirectErrorStream(redirectErrorStream);
        process = builder.start();

        if (timeOutInterval > 0) {
            timeOutTimer = new Timer("Shell command timeout");
            timeoutTimerTask = new ShellTimeoutTimerTask(this);
            // One time scheduling.
            timeOutTimer.schedule(timeoutTimerTask, timeOutInterval);
        }
        final BufferedReader errReader =
            new BufferedReader(new InputStreamReader(process
                                                     .getErrorStream()));
        BufferedReader inReader =
            new BufferedReader(new InputStreamReader(process
                                                     .getInputStream()));
        final StringBuffer errMsg = new StringBuffer();

        // read error and input streams as this would free up the buffers
        // free the error stream buffer
        Thread errThread = new Thread() {
            @Override
            public void run() {
                try {
                    String line = errReader.readLine();
                    while ((line != null) && !isInterrupted()) {
                        errMsg.append(line);
                        errMsg.append(System.getProperty("line.separator"));
                        line = errReader.readLine();
                    }
                } catch (IOException ioe) {
                    LOG.warn("Error reading the error stream", ioe);
                }
            }
        };
        try {
            errThread.start();
        } catch (IllegalStateException ignored) {
        }
        try {
            parseExecResult(inReader); // parse the output
            // clear the input stream buffer
            String line = inReader.readLine();
            while (line != null) {
                line = inReader.readLine();
            }
            // wait for the process to finish and check the exit code
            exitCode = process.waitFor();
            // make sure that the error thread exits
            joinThread(errThread);
            completed.set(true);
            // the timeout thread handling
            // taken care in finally block
            if (exitCode != 0) {
                throw new ExitCodeException(exitCode, errMsg.toString());
            }
        } catch (InterruptedException ie) {
            throw new IOException(ie.toString());
        } finally {
            if (timeOutTimer != null) {
                timeOutTimer.cancel();
            }
            // close the input stream
            try {
                // JDK 7 tries to automatically drain the input streams for us
                // when the process exits, but since close is not synchronized,
                // it creates a race if we close the stream first and the same
                // fd is recycled. the stream draining thread will attempt to
                // drain that fd!! it may block, OOM, or cause bizarre behavior
                // see: https://bugs.openjdk.java.net/browse/JDK-8024521
                // issue is fixed in build 7u60
                InputStream stdout = process.getInputStream();
                synchronized (stdout) {
                    inReader.close();
                }
            } catch (IOException ioe) {
                LOG.warn("Error while closing the input stream", ioe);
            }
            if (!completed.get()) {
                errThread.interrupt();
                joinThread(errThread);
            }
            try {
                InputStream stderr = process.getErrorStream();
                synchronized (stderr) {
                    errReader.close();
                }
            } catch (IOException ioe) {
                LOG.warn("Error while closing the error stream", ioe);
            }
            process.destroy();
            lastTime = System.currentTimeMillis();
        }
    }
private void runCommand ( ) throws IOException { ProcessBuilder builder = new ProcessBuilder ( getExecString ( ) ) ; Timer timeOutTimer = null ; ShellTimeoutTimerTask timeoutTimerTask ; timedOut = new AtomicBoolean ( false ) ; completed = new AtomicBoolean ( false ) ; if ( environment != null ) { builder . environment ( ) . putAll ( this . environment ) ; } if ( dir != null ) { builder . directory ( this . dir ) ; } builder . redirectErrorStream ( redirectErrorStream ) ; process = builder . start ( ) ; if ( timeOutInterval > 0 ) { timeOutTimer = new Timer ( "Shell command timeout" ) ; timeoutTimerTask = new ShellTimeoutTimerTask ( this ) ; timeOutTimer . schedule ( timeoutTimerTask , timeOutInterval ) ; } final BufferedReader errReader = new BufferedReader ( new InputStreamReader ( process . getErrorStream ( ) ) ) ; BufferedReader inReader = new BufferedReader ( new InputStreamReader ( process . getInputStream ( ) ) ) ; final StringBuffer errMsg = new StringBuffer ( ) ; Thread errThread = new Thread ( ) { @ Override public void run ( ) { try { String line = errReader . readLine ( ) ; while ( ( line != null ) && ! isInterrupted ( ) ) { errMsg . append ( line ) ; errMsg . append ( System . getProperty ( "line.separator" ) ) ; line = errReader . readLine ( ) ; } } catch ( IOException ioe ) { LOG . warn ( "Error reading the error stream" , ioe ) ; } } } ; try { errThread . start ( ) ; } catch ( IllegalStateException ignored ) { } try { parseExecResult ( inReader ) ; String line = inReader . readLine ( ) ; while ( line != null ) { line = inReader . readLine ( ) ; } exitCode = process . waitFor ( ) ; joinThread ( errThread ) ; completed . set ( true ) ; if ( exitCode != 0 ) { throw new ExitCodeException ( exitCode , errMsg . toString ( ) ) ; } } catch ( InterruptedException ie ) { throw new IOException ( ie . toString ( ) ) ; } finally { if ( timeOutTimer != null ) { timeOutTimer . cancel ( ) ; } try { InputStream stdout = process . getInputStream ( ) ; synchronized ( stdout ) { inReader . close ( ) ; } } catch ( IOException ioe ) { LOG . warn ( "Error while closing the input stream" , ioe ) ; } if ( ! completed . get ( ) ) { errThread . interrupt ( ) ; joinThread ( errThread ) ; } try { InputStream stderr = process . getErrorStream ( ) ; synchronized ( stderr ) { errReader . close ( ) ; } } catch ( IOException ioe ) { LOG . warn ( "Error while closing the error stream" , ioe ) ; } process . destroy ( ) ; lastTime = System . currentTimeMillis ( ) ; } }
Run a command