how to kill runtime.exec?-Collection of common programming errors

For this, you can employ the features present in java.util.concurrent

In your existing class containing your UI, you have to add something similar to this:

//class variable to store the future of your task
private Future taskFuture = null;

//to be called from button "Start" action handler
public void actionStart() {

  //don't double start, if there is one already running
  if(taskFuture == null || taskFuture.isDone()) {

    //create the new runnable instance, with the proper commands to execute
    MyShellExecutor ex = new MyShellExecutor(new String[] { "sh",testPath + "/install.sh", cmd, "&" });

    //we only need one additional Thread now, but this part can be tailored to fit different needs
    ExecutorService newThreadExecutor = Executors.newSingleThreadExecutor();

    //start the execution of the task, which will start execution of the shell command
    taskFuture = newThreadExecutor.submit(ex);
  }
}

//to be called from button "Stop" action handler
public void actionStop() {
  //if not already done, or cancelled, cancel it
  if(taskFuture !=null && !taskFuture.isDone()) {
    taskFuture.cancel(true);
  }
}

The main component doing the job is the Runnable which I named MyShellExecutor, and looks like this:

public class MyShellExecutor implements Runnable {

    //stores the command to be executed
    private final String[] toExecute;

    public MyShellExecutor(String[] toExecute) {
        this.toExecute=toExecute;
    }

    public void run() {
        Runtime runtime = Runtime.getRuntime();
        Process process = null;

        try {
            process = runtime.exec(toExecute);

            int exitValue = process.waitFor();
            System.out.println("exit value: " + exitValue);
            BufferedReader buf = new BufferedReader(new InputStreamReader(process.getInputStream()));

            String line = "";
            while ((line = buf.readLine()) != null) {
                System.out.println("exec response: " + line);
                //do whatever you need to do
            }

        } catch (InterruptedException e) {
            //thread was interrupted.
            if(process!=null) { process.destroy(); }
            //reset interrupted flag
            Thread.currentThread().interrupt();

        } catch (Exception e) {
            //an other error occurred
            if(process!=null) { process.destroy(); }
        }

    }
}

Note: when running time consuming operations, be sure not to do it on the UI thread. That just blocks the user, and doesn’t provide a nice user experience. Always do anzthing that might make the user wait on a different Thread.

Recommended reading: Java Concurrency In Practice