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