Archive: HOWTO: Close a java application


HOWTO: Close a java application
Hi

heres what i want to do:

I want the installer to shutdown a java application (a gui started with a command line order like java.exe -jar myapplication). The problem is that the app also has an icon in the systray, so if you close the app window, the icon in the taskbar still remains there and the java app is also still running (its using a dll file to be in the systray).

I used the KillProcDLL Plugin but the problem is that if you are a developer, your development environment is also being closed. Currently i managed to solve that problem with a warning and about 6 java.exe kills running in the installer to ensure that my application is closed, but isnt there an other way ? (I hate warnings)

How can i kill that dll and the app window ?


To Close the java application, you need to write the start/stop method in you java application.

You can follow the tomcat method of starting/stoping application.

1. While starting create a socket and listen for it.
2. To Stop connect to that port and send shutdown message.

Here is the sample code I have.

Hope this helps you, please let me know, if you need any more information on this

-Sundaram

/*
* Deamon.java
*
* Created on April 20, 2004, 1:54 PM
*/
import java.io.*;
import java.util.*;
import java.beans.IndexedPropertyDescriptor;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.security.AccessControlException;
import java.sql.Timestamp;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Random;

import java.rmi.*;
import java.rmi.registry.*;
import javax.rmi.*;

public class Deamon {

public static String SERVERIP ="127.0.0.1";
public static int SHUT_PORT=9191;

protected static Deamon server = null;

/**
* Use shutdown hook flag.
*/
protected boolean useShutdownHook = true;

/**
* The shutdown command string we are looking for.
*/
private String shutdown = "SHUTDOWN";

/**
* Shutdown hook.
*/
protected Thread shutdownHook = null;

/** Creates a new instance of Deamon */
public Deamon() {
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {

server = new Deamon();

try {
String command = "start";
if (args.length > 0) {
command = args[args.length - 1];
}
System.out.println("Args: " + command);

if (command.equals("startd") ||command.equals("start")) {
server.start();
} else if (command.equals("stopd")|| command.equals("stop")) {
server.stop();
}
} catch (Throwable t) {
t.printStackTrace();
}

}

public void startWriting() {
PrintWriter pw = null;

String fileName ="c:\\test.txt";
try {

FileWriter fw = new FileWriter(new File(fileName), true);
pw = new PrintWriter(fw);

while(true){
pw.println(new Date().toString() + " : Waiting.....\n" );

pw.flush() ;
Thread.sleep((60 * 60)* 2);
}


}catch(Exception ex){
System.out.println("Unable to open the file :" + ex);
}

}

public void start() {

try {
server= this;
// Wait for shutdown message to stop
new Thread(){
public void run() {
System.out.println("Calling await");
await();
}
}.start();


startRmiRegistry();
startWriting();


} catch( Exception ex) {
System.out.println("Error : " + ex.getMessage() );
}


}


public void stop() {

// Stop the existing server
try {
Socket socket = new Socket(SERVERIP, SHUT_PORT);
OutputStream stream = socket.getOutputStream();
// String shutdown = server.getShutdown();
for (int i = 0; i < shutdown.length(); i++)
stream.write(shutdown.charAt(i));
stream.flush();
stream.close();
socket.close();
} catch (IOException e) {
System.out.println("App.stop: " + e);
// e.printStackTrace(System.out);
System.exit(1);
}

System.out.println("Done!");
System.exit(0);
}

// Start RMI Registry
public void startRmiRegistry() {
// ==================== Start RMi registry ===============
try {
Registry registry = LocateRegistry.createRegistry(1099);
System.out.println("RMI registry started");
} catch ( Exception x) {
System.out.println("Error while start RMI registry");
}
}


/**
* Wait until a proper shutdown command is received, then return.
*/
public void await() {

// Set up a server socket to wait on
ServerSocket serverSocket = null;
System.out.println("creating server socket");
try {
serverSocket =
new ServerSocket(SHUT_PORT, 1,
InetAddress.getByName("127.0.0.1"));
} catch (IOException e) {
System.err.println("StandardServer.await: create[" + SHUT_PORT
+ "]: " + e);
e.printStackTrace();
System.exit(1);
}

// Loop waiting for a connection and a valid command
while (true) {

// Wait for the next connection
Socket socket = null;
InputStream stream = null;
try {
socket = serverSocket.accept();
socket.setSoTimeout(10 * 1000); // Ten seconds
stream = socket.getInputStream();
} catch (AccessControlException ace) {
System.err.println("StandardServer.accept security exception: "
+ ace.getMessage());
continue;
} catch (IOException e) {
System.err.println("StandardServer.await: accept: " + e);
e.printStackTrace();
System.exit(1);
}

// Read a set of characters from the socket
StringBuffer command = new StringBuffer();
Random random=null;
int expected = 1024; // Cut off to avoid DoS attack
while (expected < shutdown.length()) {
if (random == null)
random = new Random(System.currentTimeMillis());
expected += (random.nextInt() % 1024);
}
while (expected > 0) {
int ch = -1;
try {
ch = stream.read();
} catch (IOException e) {
System.err.println("StandardServer.await: read: " + e);
e.printStackTrace();
ch = -1;
}
if (ch < 32) // Control character or EOF terminates loop
break;
command.append((char) ch);
expected--;
}

// Close the socket now that we are done with it
try {
socket.close();
} catch (IOException e) {
;
}

// Match against our command string
boolean match = command.toString().equals(shutdown);
if (match) {
break;
} else
System.err.println("StandardServer.await: Invalid command '" +
command.toString() + "' received");

}

// Close the server socket and return
try {
serverSocket.close();
} catch (IOException e) {
;
}
System.out.println("Shuting down!!!");
System.exit(0);
}

}


I havent tried the code above yet, the developer has to include it in the next program version, but if its working how to connect to that socket from within NSIS, do you have a sample code for that too ?

But its good to see that there is an other way, killing javaw.exe x 5 isnt a good solution, like i said, on the developers machine i killed the Java Development Environment when testing the installer ;)