1

I have created a Java application where the main method (start of the program) initiates a Process object and an object of MainWindow class which creates a JFrame.

public static void main(String[] args) throws Exception {

File file = new File("./access/run.bat"); 
ProcessBuilder process_builder = new ProcessBuilder("cmd", "/c", file.getName());
process_builder.directory(file.getParentFile());
Process process = process_builder.start();
MainWindow window = new MainWindow(process);

}

I would like to terminate (kill) the process which has been instantiated with a process.destroy() when the window has been closed. Here is some code of the MainWindow class:

public MainWindow(final Process process) throws TransformerException, ParserConfigurationException, Exception{  

JFrame mainWindowFrame = new JFrame();

*****some code here*****        

mainWindowFrame.addWindowListener(new WindowListener() {

public void windowClosed(WindowEvent arg0) {

    process.destroy();
    System.exit(0);
    }

*****some code here*****    
  }

}

When the window is closed, unfortunately, the process is not killed...can anyone give me an explanation for this and a possible solution? Thanks!!!

Anto
  • 4,265
  • 14
  • 63
  • 113

2 Answers2

1

According to the documentation here then windowClosed is called only if the window is disposed. To do that, you can either call dispose on the window or set the default close operation: in your code, after creating the JFrame, add the following:

mainWindowFrame.setDefaultCloseOperation(javax.swing.JFrame.DISPOSE_ON_CLOSE);

After looking at your code, I suggest you work differently: in your listener, you are destroying the process and then exiting. therefore, you can set the deafualt close operation to exit and then implement the process destroying in the
implementation of windowClosing method : modifying the code of MainWindow to the following:

public MainWindow(final Process process) throws TransformerException, ParserConfigurationException, Exception{  

JFrame mainWindowFrame = new JFrame();
mainWindowFrame.setDefaultCloseOperation(javax.swing.JFrame.EXIT_ON_CLOSE);

*****some code here*****        

mainWindowFrame.addWindowListener(new WindowListener() {

public void windowClosing(WindowEvent arg0) {

    process.destroy();

    }

*****some code here*****    
  }

}
  • Thanks for the suggestion, but it doesn't work still, the process is still running – Anto Sep 10 '11 at 18:25
  • what I mentioned will make the method get called so that the destroy() gets executed in the first place as it was not running before. but it seems your run.bat file is starting other processes and these won't be destroyed by destroy() on your process. check the following post [here](http://stackoverflow.com/questions/6356340/killing-a-process-using-java) –  Sep 10 '11 at 18:49
0

The Javadoc of the Process class says this :

 The subprocess is not killed when there are no more references 
 to the Process object, but rather the subprocess 
 continues executing asynchronously.

There is no requirement that a process represented 
by a Process object execute asynchronously or concurrently 
with respect to the Java process that owns the Process object.

After searching on the Internet, it seems that it's a issue in the Java platform since Java 1.3. I found this blog entry that explains many issues about Process in Java.

The problem is that the process becomes an orphan after killing the application. In your code, you are killing the Process from the GUI since the GUI (the MainWindow class) has its own thread and it is not the Process parent. It's a parent/child problem. There are two ways to correct that :

  1. Since the main thread is the parent process, so the main thread must call the destroy method. So you must keep a reference to the process object.

  2. The second way is to create the process while launching the MainWindow. In the argument of the MainWindow class, you can pass the arguments of the process. So when the windowClosed method is called, if the MainWindow is closed, the Process will be destroy since the latter is the children of the MainWindow.

Dimitri
  • 8,122
  • 19
  • 71
  • 128
  • It will depend on what run.bat does. If other processes are started by the bat file, they will not be terminated. –  Sep 10 '11 at 19:39