public static CommandLineCallable executeCommandLineAsCallable()

in src/main/java/org/apache/maven/shared/utils/cli/CommandLineUtils.java [218:342]


    public static CommandLineCallable executeCommandLineAsCallable(
            @Nonnull final Commandline cl,
            @Nullable final InputStream systemIn,
            final StreamConsumer systemOut,
            final StreamConsumer systemErr,
            final int timeoutInSeconds,
            @Nullable final Runnable runAfterProcessTermination,
            @Nullable final Charset streamCharset)
            throws CommandLineException {
        //noinspection ConstantConditions
        if (cl == null) {
            throw new IllegalArgumentException("cl cannot be null.");
        }

        final Process p = cl.execute();

        final Thread processHook = new Thread() {

            {
                this.setName("CommandLineUtils process shutdown hook");
                this.setContextClassLoader(null);
            }

            @Override
            public void run() {
                p.destroy();
            }
        };

        ShutdownHookUtils.addShutDownHook(processHook);

        return new CommandLineCallable() {

            @Override
            public Integer call() throws CommandLineException {
                StreamPollFeeder inputFeeder = null;
                StreamPumper outputPumper = null;
                StreamPumper errorPumper = null;
                try {
                    if (systemIn != null) {
                        inputFeeder = new StreamPollFeeder(systemIn, p.getOutputStream());
                        inputFeeder.setName("StreamPollFeeder-systemIn");
                        inputFeeder.start();
                    }

                    outputPumper = new StreamPumper(p.getInputStream(), systemOut);
                    outputPumper.setName("StreamPumper-systemOut");
                    outputPumper.start();

                    errorPumper = new StreamPumper(p.getErrorStream(), systemErr);
                    errorPumper.setName("StreamPumper-systemErr");
                    errorPumper.start();

                    if (timeoutInSeconds > 0 && !p.waitFor(timeoutInSeconds, TimeUnit.SECONDS)) {
                        throw new CommandLineTimeOutException(
                                String.format("Process timed out after %d seconds.", timeoutInSeconds));
                    }

                    int returnValue = p.waitFor();

                    // TODO Find out if waitUntilDone needs to be called using a try-finally construct. The method may
                    // throw an
                    //      InterruptedException so that calls to waitUntilDone may be skipped.
                    //                    try
                    //                    {
                    //                        if ( inputFeeder != null )
                    //                        {
                    //                            inputFeeder.waitUntilDone();
                    //                        }
                    //                    }
                    //                    finally
                    //                    {
                    //                        try
                    //                        {
                    //                            outputPumper.waitUntilDone();
                    //                        }
                    //                        finally
                    //                        {
                    //                            errorPumper.waitUntilDone();
                    //                        }
                    //                    }
                    if (inputFeeder != null) {
                        inputFeeder.waitUntilDone();
                    }

                    outputPumper.waitUntilDone();
                    errorPumper.waitUntilDone();

                    if (inputFeeder != null && inputFeeder.getException() != null) {
                        throw new CommandLineException("Failure processing stdin.", inputFeeder.getException());
                    }

                    if (outputPumper.getException() != null) {
                        throw new CommandLineException("Failure processing stdout.", outputPumper.getException());
                    }

                    if (errorPumper.getException() != null) {
                        throw new CommandLineException("Failure processing stderr.", errorPumper.getException());
                    }

                    return returnValue;
                } catch (InterruptedException ex) {
                    Thread.currentThread().interrupt();
                    throw new CommandLineTimeOutException(
                            "Error while executing external command, process killed.", ex);
                } finally {
                    if (outputPumper != null) {
                        outputPumper.disable();
                    }
                    if (errorPumper != null) {
                        errorPumper.disable();
                    }

                    try {
                        if (runAfterProcessTermination != null) {
                            runAfterProcessTermination.run();
                        }
                    } finally {
                        ShutdownHookUtils.removeShutdownHook(processHook);
                        processHook.run();
                    }
                }
            }
        };
    }