-1

I am trying to write a simple web server in java, but stuck in stopping it. Here is a piece of sample code:

    public static void main(String... args) {

    args = new String[]{"stop"};
    Server s = Server.getServerInstance();
    s.init();
    if (args.length > 0) {
        for (int i = 0; i < args.length; i++) {
            if (args[i].equals("start")) {
                   System.out.println(s);
                   s.start();
            } else if (args[i].equals("stop")) {
                   System.out.println(s);
                   s.stop();
            }
        }
    }
}

public class Server {

private static Server serverInstance = null;
private volatile boolean running = false;
private Thread serverthread = null;


private Server() {}

public static synchronized Server getServerInstance()
{
    if(serverInstance == null)
    {
        serverInstance = new Server();
    }
    return serverInstance;
}

public void init()
{
    Runnable r = new ServerThread();
    serverthread = new Thread(r);
}

public void start()
{
    running = true;
    if(serverthread!=null)
    {
        serverthread.start();
    }
}

public void stop()
{
    running = false;
    if(serverthread!=null)
    {
        try {
            serverthread.join(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

class ServerThread implements Runnable
{
    @Override
    public void run() {
        while(running)
        {
            //some action here...
            System.out.println("RUNNING..");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

}

I packaged all these codes into a jar file and used java -cp *.jar CLASS_NAME args commend to start and stop the server. The server can start, but has never be stopped by pass into a stop arg. I debugged, and found that the Boolean value running is never changed..why? How can I implement the stop method in a elegant way? Thanks !!!!

FThompson
  • 28,352
  • 13
  • 60
  • 93
Willie
  • 13
  • 1
  • 2
    When you run java a second time, it creates a whole new process, the 's.stop()' call isn't connected in any way to the s that was started by the first process. – Thomas Apr 23 '13 at 02:36
  • You need a start/stop script – Alexandre Lavoie Apr 23 '13 at 02:37
  • Hi Thomas, please note that i used a singleton pattern, an i print out the Server instance, they are one instance beyond twice execution. and leonbloy: – Willie Apr 23 '13 at 02:48
  • the reason why i add tomcat is that i saw tomcat source file,and try to find a good way out.. – Willie Apr 23 '13 at 02:49
  • A singleton assures a single instance... per process. The second java invocation starts a second process, with its own copy. – Thomas Apr 23 '13 at 03:00
  • @Thomas thanks.. i got the key point.. – Willie Apr 23 '13 at 06:28

2 Answers2

0

Based on your code, I would assume that the instance of the server you are trying to stop isn't the one that is running.

Instead, try this.

public static void main(String... args) {

    Server s = Server.getServerInstance();
    s.init();
    s.start();
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    s.stop();
}

This will start your server, wait 5 seconds and close it.

If you want to stop the server that is running in a separate process, you will need to look at using something like sockets to enable cross process communications.

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • hi Mad, what do you mean by separate process ? separate Server class instance ? i used singleton to make sure i would get same instance. thanks.. – Willie Apr 23 '13 at 03:01
  • If you were to run you program (as is) with `start` as the command line argument. It will create a process, in which it will create a thread that is your server. This process will only ever be able to create a single instance of the server. If you run it again with `start` as the command line argument, it will create a new process with a new thread that is server. This is why you can't stop it. Each time you run the program, it is creating a separate process which has no knowledge of all the other processes/threads you have created – MadProgrammer Apr 23 '13 at 03:04
  • Thanks Mad,your explanation make scene and do you have any suggestion or idea for me to stop a started server by command ? i want to use a shell script with java command "java -cp JAR_FILES BOOTSTRAP_CLASS_NAME args" here the args will be [start,stop,status]. – Willie Apr 23 '13 at 03:22
  • The only way to do what you want is to use some kind of IPC (inter-process communications) API such as sockets. – MadProgrammer Apr 23 '13 at 03:24
0

I suggest you to use a script like that (of course if your Java server is running on Linux)

#!/bin/sh

PROGRAM_NAME=servername
PROGRAM_HOME=/usr/local/servername
PIDFILE=/var/run/$PROGRAM_NAME.pid

application_start() {
    CMDLINE="/usr/lib/java/bin/java -jar $PROGRAM_NAME.jar"
    echo -n "Starting $PROGRAM_NAME daemon: $CMDLINE"
    cd $PROGRAM_HOME

    /usr/lib/java/bin/java -classpath lib -jar $PROGRAM_NAME.jar &
    ps -Ao pid,command | grep java | grep $PROGRAM_NAME.jar | awk '{print $1}' > $PIDFILE
    echo
}

application_stop() {
        echo -n "Stopping $PROGRAM_NAME daemon..."

        if [ -r $PIDFILE ]; then
                PID=`cat $PIDFILE`
                if [ $PID -gt 0 ]; then
                        kill $PID
                        echo
                        sleep 1
                        fi
                rm -f $PIDFILE
        fi
        killall $PROGRAM_NAME
}

application_restart() {
    application_stop
    sleep 1
    application_start
}

case "$1" in
'start')
    application_start
    ;;
'stop')
    application_stop
    ;;
'restart')
    application_restart
    ;;
*)
    echo "usage $0 start|stop|restart"
esac
Alexandre Lavoie
  • 8,711
  • 3
  • 31
  • 72
  • Thanks Alex,please allow me calling you this way.. i totally understand that i can use a shell script,i used this way before, but simply kill the process is not a good way to stop the server. all service suddenly killed may lead data corruption or something.. "not a elegant way to stop the server.."-- i saw this quote in book :) but still thank you .. – Willie Apr 23 '13 at 02:53
  • Another better way maybe, catch the kill signal : http://stackoverflow.com/questions/2541597/how-to-gracefully-handle-the-sigkill-signal-in-java – Alexandre Lavoie Apr 23 '13 at 03:15