How to stop Java HTTP server

How to stop Java HTTP server

Post by Shiladity » Fri, 15 Oct 2010 05:53:27


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
 
 
 

How to stop Java HTTP server

Post by Tom Anders » Fri, 15 Oct 2010 21:12:12

n Wed, 13 Oct 2010, Shiladitya wrote:


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();
}


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

 
 
 

How to stop Java HTTP server

Post by Shiladity » Sat, 16 Oct 2010 02:16:35

n Oct 14, 8:12m, Tom Anderson < XXXX@XXXXX.COM > wrote:
> > hread.slee>(>000);
>>>>}
> > httpS>rv>rExe.stop();
>
> That's the wrong way to do it. Rather than sleeping in a l>op, this thread
> should wait on a monitor, and threads which want to stop t>e server should
> noti>y >hat monitor.
>
> The main code >ou>d look like:
>
>>server.start();
> synchronized (te>minationLock) {
> while (!terminated) term>na>ionLock.wait();} >> >> server.stop();
>
> Code which want> t> stop it can go:
>
> synchronized>(terminationLock) {
> t>rm>nati>n>ock.notify();
>
> }
> > I have set up a handler for a URL (/terminateCom>a>d). So if anyone send
> > a request to this URL, the terminated flag shoul> >e set and main thread
> > shou>d >t>p the http server.
>
> > But I can't figure out how to set the flag fro> >ne of the handlers so
> > that main >hr>ad gets interrupted.
>
> The handler has to have a reference to the plac> the flag lives. If the
> flag is a static variable on a class, then it can >o directly >o >he class
> by name:
>
> Main>lass.terminated = true;
> synchron>zed (terminationLock) {
> MainCla>s.>ermi>at>onLock.notify();
>
> }
>
> Although of course it would be bett>r >o wrap that in a method: >> >> MainClass.terminat>();
>
> class MainClass {
> pr>vate static boolean terminated;
> pr>vate static Object terminationLock;
> > public static void ter>inate() {
> terminated = t>ue;
> synchronized (ter>inationLock)>{
> gt;> gt;> terminationLock.notify();
> }
> }
>> > }
>
> If it's on an object, then you will need to pass a re>er>nce to that
> object to the h>ndler somehow, perhaps when you construct it.
> void main(String... args) {
> HttpServer server = Htt>Server.create();
> ServerController controller = new ServerControl>er(server);
> HttpHandler terminationHandler = new Te>minationHandler(controller);
> > gt;serv>r.>reateContext("/terminate", terminationHandler);> > new Thread(controller)>start;
>
> }
>
> class ServerC>ntroller implements Runnable {
> private Htt>Server server;
> private boolean terminate>;
> private Object term>nationLo>k = new Object();
> gt;public ServerController(>ttpServer server) {
> this>server = server;
> > }
> public void run() {
> ser>er.start();
> gt;synchronized (terminationLock) {
> > gt;while (!termin>ted) terminationLock.wait(); >> }
> > catch (InterruptedException e> {}
> gt;> }> > gt;> server.stop();
> }
> public void terminate() { >> terminated = true;
> synchronized (termi>ationLock) {
> terminationLock.notify();
> gt;}
> }
>
> }
>
> >ou>could dispense with the terminationLock by using the Server>ontroller
> itself to wait and notify on, but i tend to st>er>way from that, and use
> private objects as lo>ks, so that the wait/notify activ>ty of the methods
> can't 'leak' across the interface.
>
> java.util.concurrent.Co>ntDownLa>ch with a count of one:
>> > class ServerController >mplements Runnab>e {
> private HttpSe>ver server; >> private CountDownLatch latch = new>CountDownLatch(1);
> gt;publ>c ServerController(HttpServer se>ver) {
> thi>.server > s>rver>
> gt;public void run() {
>