How to stop Java HTTP server

Discussion in 'Java' started by Shiladitya, Oct 13, 2010.

  1. Shiladitya

    Shiladitya Guest

    Hi,
    I am using the embedded Sun Java Http server : com.sun.net.httpserver.

    I wrote code for setting the executor, adding context and starting it.
    This is written in the main thread.
    I need a way to call httpServerExe.stop() from this thread.

    So the main thread can be like this:


    {
    httpServerExe.start();
    while(!terminated) {
    Thread.sleep(4000);
    }
    httpServerExe.stop();

    }

    I have set up a handler for a URL (/terminateCommand). So if anyone
    send a request to this URL, the terminated flag should be set and main
    thread should stop the http server.

    But I can't figure out how to set the flag from one of the handlers so
    that main thread gets interrupted.

    TIA
    Shiladitya
     
    Shiladitya, Oct 13, 2010
    #1
    1. Advertising

  2. Shiladitya

    Tom Anderson Guest

    On Wed, 13 Oct 2010, Shiladitya wrote:

    > I need a way to call httpServerExe.stop() from this thread.
    >
    > So the main thread can be like this:
    >
    > httpServerExe.start();
    > while(!terminated) {
    > Thread.sleep(4000);
    > }
    > httpServerExe.stop();


    That's the wrong way to do it. Rather than sleeping in a loop, this thread
    should wait on a monitor, and threads which want to stop the server should
    notify that monitor.

    The main code would look like:

    server.start();
    synchronized (terminationLock) {
    while (!terminated) terminationLock.wait();
    }
    server.stop();

    Code which wants to stop it can go:

    terminated = true;
    synchronized (terminationLock) {
    terminationLock.notify();
    }

    > I have set up a handler for a URL (/terminateCommand). So if anyone send
    > a request to this URL, the terminated flag should be set and main thread
    > should stop the http server.
    >
    > But I can't figure out how to set the flag from one of the handlers so
    > that main thread gets interrupted.


    The handler has to have a reference to the place the flag lives. If the
    flag is a static variable on a class, then it can go directly to the class
    by name:

    MainClass.terminated = true;
    synchronized (terminationLock) {
    MainClass.terminationLock.notify();
    }

    Although of course it would be better to wrap that in a method:

    MainClass.terminate();

    class MainClass {
    private static boolean terminated;
    private static Object terminationLock;
    public static void terminate() {
    terminated = true;
    synchronized (terminationLock) {
    terminationLock.notify();
    }
    }
    }

    If it's on an object, then you will need to pass a reference to that
    object to the handler somehow, perhaps when you construct it.

    void main(String... args) {
    HttpServer server = HttpServer.create();
    ServerController controller = new ServerController(server);
    HttpHandler terminationHandler = new TerminationHandler(controller);
    server.createContext("/terminate", terminationHandler);
    new Thread(controller).start;
    }

    class ServerController implements Runnable {
    private HttpServer server;
    private boolean terminated;
    private Object terminationLock = new Object();
    public ServerController(HttpServer server) {
    this.server = server;
    }
    public void run() {
    server.start();
    synchronized (terminationLock) {
    try {
    while (!terminated) terminationLock.wait();
    }
    catch (InterruptedException e) {}
    }
    server.stop();
    }
    public void terminate() {
    terminated = true;
    synchronized (terminationLock) {
    terminationLock.notify();
    }
    }
    }

    You could dispense with the terminationLock by using the ServerController
    itself to wait and notify on, but i tend to steer way from that, and use
    private objects as locks, so that the wait/notify activity of the methods
    can't 'leak' across the interface.

    An even better way to do this, actually, would be with a
    java.util.concurrent.CountDownLatch with a count of one:

    class ServerController implements Runnable {
    private HttpServer server;
    private CountDownLatch latch = new CountDownLatch(1);
    public ServerController(HttpServer server) {
    this.server = server;
    }
    public void run() {
    server.start();
    try {
    latch.await();
    }
    catch (InterruptedException e) {}
    server.stop();
    }
    public void terminate() {
    latch.countDown();
    }
    }

    tom

    --
    you can't feel your stomack with glory -- Czako
     
    Tom Anderson, Oct 14, 2010
    #2
    1. Advertising

  3. Shiladitya

    Shiladitya Guest

    On Oct 14, 8:12 am, Tom Anderson <> wrote:
    > On Wed, 13 Oct 2010, Shiladitya wrote:
    > > I need a way to call httpServerExe.stop() from this thread.

    >
    > > So the main thread can be like this:

    >
    > >       httpServerExe.start();
    > >       while(!terminated) {
    > >          Thread.sleep(4000);
    > >         }
    > >         httpServerExe.stop();

    >
    > That's the wrong way to do it. Rather than sleeping in a loop, this thread
    > should wait on a monitor, and threads which want to stop the server should
    > notify that monitor.
    >
    > The main code would look like:
    >
    > server.start();
    > synchronized (terminationLock) {
    >         while (!terminated) terminationLock.wait();}
    >
    > server.stop();
    >
    > Code which wants to stop it can go:
    >
    > terminated = true;
    > synchronized (terminationLock) {
    >         terminationLock.notify();
    >
    > }
    > > I have set up a handler for a URL (/terminateCommand). So if anyone send
    > > a request to this URL, the terminated flag should be set and main thread
    > > should stop the http server.

    >
    > > But I can't figure out how to set the flag from one of the handlers so
    > > that main thread gets interrupted.

    >
    > The handler has to have a reference to the place the flag lives. If the
    > flag is a static variable on a class, then it can go directly to the class
    > by name:
    >
    > MainClass.terminated = true;
    > synchronized (terminationLock) {
    >         MainClass.terminationLock.notify();
    >
    > }
    >
    > Although of course it would be better to wrap that in a method:
    >
    > MainClass.terminate();
    >
    > class MainClass {
    >         private static boolean terminated;
    >         private static Object terminationLock;
    >         public static void terminate() {
    >                 terminated = true;
    >                 synchronized (terminationLock) {
    >                         terminationLock.notify();
    >                 }
    >         }
    >
    > }
    >
    > If it's on an object, then you will need to pass a reference to that
    > object to the handler somehow, perhaps when you construct it.
    >
    > void main(String... args) {
    >         HttpServer server = HttpServer.create();
    >         ServerController controller = new ServerController(server);
    >         HttpHandler terminationHandler = new TerminationHandler(controller);
    >         server.createContext("/terminate", terminationHandler);
    >         new Thread(controller).start;
    >
    > }
    >
    > class ServerController implements Runnable {
    >         private HttpServer server;
    >         private boolean terminated;
    >         private Object terminationLock = new Object();
    >         public ServerController(HttpServer server) {
    >                 this.server = server;
    >         }
    >         public void run() {
    >                 server.start();
    >                 synchronized (terminationLock) {
    >                         try {
    >                                 while (!terminated) terminationLock.wait();
    >                         }
    >                         catch (InterruptedException e) {}
    >                 }
    >                 server.stop();
    >         }
    >         public void terminate() {
    >                 terminated = true;
    >                 synchronized (terminationLock) {
    >                         terminationLock.notify();
    >                 }
    >         }
    >
    > }
    >
    > You could dispense with the terminationLock by using the ServerController
    > itself to wait and notify on, but i tend to steer way from that, and use
    > private objects as locks, so that the wait/notify activity of the methods
    > can't 'leak' across the interface.
    >
    > An even better way to do this, actually, would be with a
    > java.util.concurrent.CountDownLatch with a count of one:
    >
    > class ServerController implements Runnable {
    >         private HttpServer server;
    >         private CountDownLatch latch = new CountDownLatch(1);
    >         public ServerController(HttpServer server) {
    >                 this.server = server;
    >         }
    >         public void run() {
    >                 server.start();
    >                 try {
    >                         latch.await();
    >                 }
    >                 catch (InterruptedException e) {}
    >                 server.stop();
    >         }
    >         public void terminate() {
    >                 latch.countDown();
    >         }
    >
    > }
    >
    > tom
    >
    > --
    > you can't feel your stomack with glory -- Czako


    That was very helpful Tom. I have tested it out and it works nicely !
     
    Shiladitya, Oct 14, 2010
    #3
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Matt Theule

    Stop Debugging doesn't stop in ASP.NET

    Matt Theule, Jul 23, 2003, in forum: ASP .Net
    Replies:
    7
    Views:
    774
    Matt Theule
    Jul 24, 2003
  2. mike
    Replies:
    5
    Views:
    1,011
    Keith M. Corbett
    Sep 21, 2004
  3. Will
    Replies:
    1
    Views:
    15,436
    Thomas Weidenfeller
    Nov 2, 2004
  4. Replies:
    3
    Views:
    846
    Guillermo
    Apr 26, 2007
  5. lkcl
    Replies:
    6
    Views:
    1,109
Loading...

Share This Page