2017-08-29 1 views
0

Ich begann die Ausführung eines testng.xml durch Apache Commons Testamentsvollstrecker libarary durch folgenden Code:Kill-Prozess von org.apache.commons.executor gestartet

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); 

Aber ich möchte eine Stopp-Taste geben, diesen Prozess zu stoppen . Ich habe versucht:

executor.getWatchdog().destroyProcess(); 

Aber das zerstört nur den Watchdog. Die von mir gestartete Datei "testng.xml" läuft jedoch weiterhin im Hintergrund. Ich möchte den Prozess, den ich in dem Befehl gegeben habe, zerstören. Ist das möglich?

+0

Warum brauchen Sie Apache Testamentsvollstrecker verwenden, um eine 'TestNG' Suite Ausführung ausgliedern? Sie sind besser dran mit dem TestNG Apis direkt in Ihrem Java-Code Nein? Bitte zeigen Sie uns auch, wie 'cl' a.k.a Ihre' CommandLine' aussieht. –

+0

@KrishnanMahadevan Ich möchte die Konsolenausgabe direkt an ein Jframe-Textfeld senden, von dem ich nicht sicher bin, ob es über TestNG-APIs möglich ist. Außerdem möchte ich es als einen anderen Thread ausführen, damit die Hauptanwendung nicht hängt. Der Befehl c1 lautet: cmd.exe/k cd "D: \ MeinProjekt" && D: && java -cp D: \ MeinProjekt \ Dienstprogramme \ *; D: \ MeinProjekt \ bin org.testng.TestNG D: \ MeinProjekt \ testng .xml –

Antwort

0

Der Grund, warum Ihre Lösung die JVM, die erzeugt wurde, nicht zum Absturz bringt, liegt vielleicht daran, dass Sie cmd.exe aufrufen und von wo aus Sie wahrscheinlich die JVM generieren. Also, wenn Sie destroyProcess() aufrufen, glaube ich, dass cmd.exe getötet wird, aber nicht java.exe.

Sie versuchen sollen, wie unter der Befehlszeile, um etwas zu ändern:

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

Hier ist eine Lösung, die für das Handeln dies nicht die Verwendung von Apache commons Testamentsvollstrecker machen, aber alles in einer einzigen JVM verwaltet und bieten auch für eine Möglichkeit, die Ausgabe und die Fehlerausgabe von TestNG abzurufen.

Diese Lösung verwendet die TestNG-APIs.

Der Haupttestläufer, die TestNG verwendet Tests auszuführen, in einem anderen Thread sieht wie unten

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() + 
        '}'; 
     } 
    } 
} 

Die Utility-Klasse, die alle Ausgabe- und Fehler Inhalt in einen Thread neu leitet, so dass sie umgeleitet werden, sieht wie folgt aus:

Diese Klasse ist meist geliehen Code aus der Lösung mit einigen Improvisationen.

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() + '\'' + 
        '}'; 
     } 
    } 
} 

Die Testklasse verwendet sieht aus wie unten

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"); 
    } 
} 

Die Ausgabe wie folgt aussieht unten

***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 
Verwandte Themen