杀死进程由org.apache.commons.executor启动

时间:2017-08-29 05:52:06

标签: java apache testng apache-commons apache-commons-exec

我通过以下代码开始通过apache commons executor libarary执行testng.xml:

DefaultExecuteResultHandler resultHandler;
        ExecuteWatchdog watchdog;
        final Executor executor;

        resultHandler = new DefaultExecuteResultHandler();
        watchdog = new ExecuteWatchdog(-1L);
        executor = new DefaultExecutor();
        executor.setStreamHandler(new PumpStreamHandler(new LogOutputStream() {

        @Override
        protected void processLine(final String line, @SuppressWarnings("unused") int level) {
           Display.getDefault().syncExec(new Runnable() {

                public void run() {

                    if (line.toLowerCase().indexOf("error") > -1) {

                        textArea.append(line+"\n");
                    } else if (line.toLowerCase().indexOf("warn") > -1) {
                        textArea.append(line+"\n");
                    } else {
                        textArea.append(line+"\n");


                    }
                }
            });
        }
    }));

    executor.setExitValue(1);
    executor.setWatchdog(watchdog);
    executor.execute(cl, resultHandler);

但我想给一个停止按钮来停止这个过程。我试过了:

executor.getWatchdog().destroyProcess();

但这只会破坏看门狗。但是我开始的testng.xml继续在后台运行。我想破坏我在命令中给出的过程。 这可能吗?

1 个答案:

答案 0 :(得分:0)

为什么你的解决方案没有杀死生成的JVM的原因可能是因为你正在调用cmd.exe并且从那里你可能正在生成JVM。因此,当您调用destroyProcess()时,我认为其cmd.exe已被杀死,但未被java.exe

您应该尝试将命令行更改为以下内容:

java -cp D:\MyProject\Utilities*;D:\MyProject\bin org.testng.TestNG D:\MyProject\testng.xml

这是一个不使用Apache commons executor执行此操作的解决方案,但是管理单个JVM中的所有内容,并提供了一种从TestNG检索输出和错误输出的方法。

此解决方案使用TestNG API。

使用TestNG运行测试的主要测试运行器在不同的线程中如下所示

import org.testng.TestNG;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class SimpleTestRunner {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        System.err.println("***Main Thread running in Thread [" + Thread.currentThread().getId() + "]***");
        ExecutorService service = Executors.newCachedThreadPool();
        WorkerThread thread = new WorkerThread(SampleTestClass.class);
        List<Future<ExecutionResults>> allResults = service.invokeAll(Collections.singletonList(thread));
        service.shutdown();
        ExecutionResults result = allResults.get(0).get();
        System.err.println("******Printing the TestNG output******");
        System.err.println(result);
        System.err.println("**************************************");
    }

    public static class WorkerThread implements Callable<ExecutionResults> {
        private Class<?>[] classes;

        WorkerThread(Class<?>... classes) {
            this.classes = classes;
        }

        @Override
        public ExecutionResults call() throws Exception {
            System.err.println("***Worker Thread running in Thread [" + Thread.currentThread().getId() + "]***");
            TestNG testNG = new TestNG();
            ExecutionResults results;
            testNG.setVerbose(2);
            ConsoleCapturer capturer = new ConsoleCapturer();
            testNG.setTestClasses(classes);
            try {
                capturer.start();
                testNG.run();
            } finally {
                ConsoleCapturer.CapturedData data = capturer.stop();
                results = new ExecutionResults(data, testNG.getStatus());
            }
            return results;
        }
    }

    public static class ExecutionResults {
        private ConsoleCapturer.CapturedData data;
        private int status;

        public ExecutionResults(ConsoleCapturer.CapturedData data, int status) {
            this.data = data;
            this.status = status;
        }

        public ConsoleCapturer.CapturedData getData() {
            return data;
        }

        public int getStatus() {
            return status;
        }

        @Override
        public String toString() {
            return "ExecutionResults{" +
                    "data=" + getData() +
                    ", status=" + getStatus() +
                    '}';
        }
    }
}

将所有输出和错误内容重定向到线程的实用程序类,以便可以将它们重定向到任何位置,如下所示:

这个类主要是来自解决方案Redirect console output to string in java的借用代码,有一些即兴创作。

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;

/**
 * This class is an improvisation of the solution provided in https://stackoverflow.com/a/30665299/679824
 */
public class ConsoleCapturer {
    private ByteArrayOutputStream baosOutput, baosError;
    private PrintStream previousOut, previousError;
    private boolean capturing;

    public void start() {
        if (capturing) {
            return;
        }

        capturing = true;
        previousOut = System.out;
        previousError = System.err;
        baosOutput = new ByteArrayOutputStream();
        baosError = new ByteArrayOutputStream();

        System.setOut(new PrintStream(new OutputStreamCombiner(previousOut, baosOutput)));
        System.setErr(new PrintStream(new OutputStreamCombiner(previousError, baosError)));
    }

    public CapturedData stop() {

        if (!capturing) {
            return new CapturedData();
        }

        System.setOut(previousOut);
        System.setErr(previousError);

        String output = baosOutput.toString();
        String error = baosError.toString();

        try {
            baosOutput.close();
            baosError.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

        baosOutput = null;
        previousOut = null;
        capturing = false;

        return new CapturedData(output, error);
    }

    private static class OutputStreamCombiner extends OutputStream {
        private OutputStream[] outputStreams;

        OutputStreamCombiner(OutputStream... outputStreams) {
            this.outputStreams = outputStreams;
        }

        public void write(int b) throws IOException {
            for (OutputStream os : outputStreams) {
                os.write(b);
            }
        }

        public void flush() throws IOException {
            for (OutputStream os : outputStreams) {
                os.flush();
            }
        }

        public void close() throws IOException {
            for (OutputStream os : outputStreams) {
                os.close();
            }
        }
    }

    public static class CapturedData {
        private String output;
        private String error;

        CapturedData() {
            this("", "");
        }

        public CapturedData(String output, String error) {
            this.output = output;
            this.error = error;
        }

        public String getError() {
            return error;
        }

        public String getOutput() {
            return output;
        }

        @Override
        public String toString() {
            return "CapturedData{" +
                    "output='" + getOutput() + '\'' +
                    ", error='" + getError() + '\'' +
                    '}';
        }
    }
}

使用的测试类如下所示

import org.testng.annotations.Test;

public class SampleTestClass {

    @Test
    public void testMethod() {
        System.err.println("This goes into the error console");
        System.out.println("This goes into the console");
    }
}

输出如下所示

***Main Thread running in Thread [1]***
***Worker Thread running in Thread [11]***
This goes into the console
This goes into the error console
PASSED: testMethod

===============================================
    Command line test
    Tests run: 1, Failures: 0, Skips: 0
===============================================


===============================================
Command line suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

******Printing the TestNG output******
ExecutionResults{data=CapturedData{output='This goes into the console
PASSED: testMethod

===============================================
    Command line test
    Tests run: 1, Failures: 0, Skips: 0
===============================================


===============================================
Command line suite
Total tests run: 1, Failures: 0, Skips: 0
===============================================

', error='This goes into the error console
'}, status=0}
**************************************

Process finished with exit code 0