Anto
Anto

Reputation: 4305

problem killing a process in a Java application

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!!!

Upvotes: 1

Views: 2503

Answers (2)

Dimitri
Dimitri

Reputation: 8290

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.

Upvotes: 0

user890904
user890904

Reputation:

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*****    
  }

}

Upvotes: 1

Related Questions