Interromper processos

4 respostas
K

Boa tarde, estou montando um frame que possui um botão, que ao ser pressionado, executa uma thread. Nesta thread, há a execução de um processo através do Runtime.

Meu problema é o seguinte: como interromper o processo da thread ao apertar o botão novamente, como um start-stop?
O método destroy() não está interrompendo.

Segue meu code:

...
public static boolean isExecuting = false;
    public static Process process;
...
public synchronized void getDiff() throws IOException 
    {
        String command = "";
        isExecuting = true;
        process = Runtime.getRuntime().exec("C:/Windows/system32/cmd.exe");
        stdin = process.getOutputStream();
        sterr = process.getErrorStream();

        command = "svn diff -r " + (getChgset() - 1) + ":" + getChgset() + " " + getUrl() + " > " + getPath() + getChgset() + ".diff" + "\n";
       
        stdin.write(command.getBytes());
        stdin.flush();
        stdin.close();
        
        boolean failed = false;
        BufferedReader brCleanUp = new BufferedReader(new InputStreamReader(sterr));
	    while ((command = brCleanUp.readLine()) != null) 
	    {
	    	//System.out.print("[Sterr]: "+ command");
	    	printLog("[Error]: " + command, true, true);	    	
	    	failed = true;
	    }
	    brCleanUp.close();
	    
	    if(!failed)
	    	printLog("Diff: "+ getChgset() + " received.", true, false);
	    exit(failed ? false : true);
    }
private void startActionPerformed() 
    {
        Thread t = new Thread() 
        {
        	@Override
        	public void run() {
        		try {
        			utils.getDiff();
        		} catch (IOException ex) {
        			Logger.getLogger(MainGui.class.getName()).log(Level.SEVERE, null, ex);
        		}
        	}
        };
        
        if(Utils.isExecuting)
        	Utils.process.destroy();
        else
        {
        	utils.printLog("Capturing diff "+chgset.getValue().toString()+"...", false, false);
        	t.start();
        }

4 Respostas

davidbuzatto

Para que o destroy funcione, vc precisa ter consumido totalmente os streams de saída e de erro do processo.
Dê uma lida nesse artigo: http://www.javaworld.com/javaworld/jw-12-2000/jw-1229-traps.html?page=1

[]´s

K

Então preciso esperar o término do processo?

davidbuzatto

Não precisa não.
Você precisa estar consumindo constantemente os streams dele. Se os streams estiverem “vazios” vc consegue destruir o processo.
Dê uma olhada no artigo. A classe StreamGobbler que ele cria é uma thread que consome constantemente os streams do processo.

[]´s

K

Coloquei o gobbler após a inicialização do processo, mas continua sem funcionar.
O Gobbler ainda dispara uma exceção “java.io.IOException: No process is on the other end of the pipe” no final do processo.

public synchronized void getDiff() throws IOException 
    {
    	isRunning = true;
        String command = "";
        process = Runtime.getRuntime().exec("cmd.exe");
        stdin = process.getOutputStream();
        sterr = process.getErrorStream();
        stout = process.getInputStream();
        
       StreamGobbler errorGobbler = new StreamGobbler(err, "ERROR");    
	    StreamGobbler outputGobbler = new StreamGobbler(in, "OUTPUT");
	        
	    // kick them off
	    errorGobbler.start();
	    outputGobbler.start();	
        
        command = "svn diff -r " + (getChgset() - 1) + ":" + getChgset() + " " + getUrl() + " > " + getPath() + getChgset() + ".diff" + "\n";
	    
        stdin.write(command.getBytes());
        stdin.flush();
        stdin.close();
        
        boolean failed = false;
        BufferedReader brCleanUp = new BufferedReader(new InputStreamReader(sterr));
	    while ((command = brCleanUp.readLine()) != null) 
	    {
	    	//System.out.print("[Sterr]: "+ command");
	    	printLog("[Error]: " + command, true, true);	    	
	    	failed = true;
	    }
	    brCleanUp.close();
	    
	    if(!failed)
	    	printLog("Diff: "+ getChgset() + " received.", true, false);
	    exit(failed ? false : true);
    }

Coloquei um print no process dentro do getDiff (classe Utils) e outro dentro do startActionPerformed (classe MainGui). O primeiro retornou um id, enquanto o segundo retornou null. Não sei se pode ter a ver, mas em todo caso…Tentei também inicializar o processo usando um método separado e depois iniciando o método dentro do getDiff(), mas assim ele não reconhece o processo.

Criado 16 de outubro de 2010
Ultima resposta 17 de out. de 2010
Respostas 4
Participantes 2