Hi Peter,

I think you are starting two processes under Windows

* one command line interpreter
* the second one is the "hg log" command which is a child process of the command line interpreter

When you kill the process the command line interpreter is killed but the second one (child process) is very likely still running since Windows has no real concept of a parent pid

* http://commons.apache.org/proper/commons-exec/faq.html#killing-child-processes
* http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4770092

Cheers,

Siegfried Goeschl


On 02.02.15 04:35, Peter Ashford wrote:
Hi there

I'm trying to use ExecuteWatchDog.destroyProcess() to kill a running
process but it doesn't seem to work.  I've pasted a minimal test case below
which shows what I'm trying to do: it creates a frame with a text area
which the process output is echoed to.  I've set it up so that ctrl + c
should kill the running process but it doesn't appear to work.

This test case changes directory to y:\ (my mapped drive where my mercurial
repository lives) and does a "hg log" which runs for a long time on my
machine, giving me time to kill the process).  If you wanted to run this
test, you'd have to choose a directory and long running process appropriate
for your machine.

I've confirmed that the break signal is being received - there's a write to
std.err in the code that executes correctly.

If anyone could help me with this, i'd really appreciate it!

Cheers!

Peter.

----------------

package jcon2;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneConstants;
import javax.swing.UIManager;
import javax.swing.text.Document;
import org.apache.commons.exec.*;

public class Test implements KeyListener {
     JFrame    frame;
     JTextArea text;
     Document  textDoc;
     boolean   breakFlag   = false;
     boolean   execProcessRunning;
     File      currentDir  = new File("y:\\");
     BufferedOutputStream execIn;

     class JCStream extends OutputStream {
         public void write(int b) throws IOException {
             writeCon(new String(new byte[]{ (byte) b}));
             moveCaretToEnd();
         }
     }

     public Test(){
         frame = new JFrame("JCon2");
         text  = new JTextArea();
         textDoc = text.getDocument();
         JScrollPane scroller = new JScrollPane(text);

scroller.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
         frame.add(scroller);
         frame.setPreferredSize(new Dimension(600,800));
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         text.addKeyListener(this);
         frame.pack();
         frame.setVisible(true);
     }


     /**
      * Write to the console
      * @param str The text to write
      */
     private void writeCon(String str){
         try {
             if(str != null && str.length()>0){
                 textDoc.insertString(textDoc.getLength(), str, null);
             }
         } catch (Exception ex) {
             // ignore
         }
     }

     private void moveCaretToEnd(){
         text.setCaretPosition(text.getDocument().getLength());
     }

     private void processCommand(String cmd) {
         writeCon("\n");

         DefaultExecutor ex = new DefaultExecutor();
         CommandLine cmdLine;

         cmdLine = new CommandLine("cmd.exe");
         cmdLine.addArguments("/E:1900 /C " + cmd);


         new Thread(()-> {
                 JCStream out = new JCStream();

                 PumpStreamHandler streamHandler = new
PumpStreamHandler(out, out, System.in);
                 ex.setStreamHandler(streamHandler);
                 ex.setWorkingDirectory(currentDir);
                 ex.setExitValues(null);
                 breakFlag = false;

                 ExecuteWatchdog watchDog = new
ExecuteWatchdog(ExecuteWatchdog.INFINITE_TIMEOUT);
                 ex.setWatchdog(watchDog);

                 new Thread(()->{
                     while(execProcessRunning){
                         if(breakFlag){
                             System.err.println("Break!");   // <<< this
happens on ctrl + c
                             watchDog.destroyProcess();      // <<< but
output to textarea isn't stopped
                             breakFlag = false;
                             return;
                         }
                         try {
                             Thread.sleep(50);
                         } catch (InterruptedException ex1) {
                             // ignore
                         }
                     }
                 }).start();

                 try {
                     execProcessRunning = true;
                     ex.execute(cmdLine);
                 } catch (IOException ex1) {
                     // ignore
                 }

                 execProcessRunning = false;
                 writeCon("\n");
             }
         ).start();
     }

     public void keyPressed(KeyEvent e) {
         int keyCode = e.getKeyCode();

         if(e.isControlDown() && keyCode == KeyEvent.VK_C){
             e.consume();
             breakFlag = true;
         }
     }
     public void keyTyped(KeyEvent e) {}
     public void keyReleased(KeyEvent e) {}

     public static void main(String[] args)  {
         try {

UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
         } catch(Exception e){
             // don't care
         }

         Test t = new Test();
         t.processCommand("hg log");
     }
}



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to