Jetty: stopping programmatically results in "1 thread cannot be stopped"

I have a built-in instance of Jetty 6.1.26. I want to disable HTTP GET sent to /shutdown . So I created a JettyShutdownServlet :

 @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setStatus(202, "Shutting down."); resp.setContentType("text/plain"); ServletOutputStream os = resp.getOutputStream(); os.println("Shutting down."); os.close(); resp.flushBuffer(); // Stop the server. try { log.info("Shutting down the server..."); server.stop(); } catch (Exception ex) { log.error("Error when stopping Jetty server: "+ex.getMessage(), ex); } 

However, when I submit the request, Jetty does not stop - the thread is held in org.mortbay.thread.QueuedThreadPool in a line using this.wait() :

  // We are idle // wait for a dispatched job synchronized (this) { if (_job==null) this.wait(getMaxIdleTimeMs()); job=_job; _job=null; } 

...

 2011-01-10 20:14:20,375 INFO org.mortbay.log jetty-6.1.26 2011-01-10 20:14:34,756 INFO org.mortbay.log Started SocketConnector@0.0.0.0 :17283 2011-01-10 20:25:40,006 INFO org.jboss.qa.mavenhoe.MavenHoeApp Shutting down the server... 2011-01-10 20:25:40,006 INFO org.mortbay.log Graceful shutdown SocketConnector@0.0.0.0 :17283 2011-01-10 20:25:40,006 INFO org.mortbay.log Graceful shutdown org.mortbay.jetty.servlet.Context@1672bbb {/,null} 2011-01-10 20:25:40,006 INFO org.mortbay.log Graceful shutdown org.mortbay.jetty.webapp.WebAppContext@18d30fb {/jsp,file:/home/ondra/work/Mavenhoe/trunk/target/classes/org/jboss/qa/mavenhoe/web/jsp} 2011-01-10 20:25:43,007 INFO org.mortbay.log Stopped SocketConnector@0.0.0.0 :17283 2011-01-10 20:25:43,009 WARN org.mortbay.log 1 threads could not be stopped 2011-01-10 20:26:43,010 INFO org.mortbay.log Shutdown hook executing 2011-01-10 20:26:43,011 INFO org.mortbay.log Shutdown hook complete 

It locks for exactly one minute, then turns off. I added "Graceful completion", which should allow me to disconnect the server from the servlet; However, it does not work, as you can see from the magazine.

I solved it like this:

 Server server = new Server( PORT ); server.setGracefulShutdown( 3000 ); server.setStopAtShutdown(true); ... server.start(); if( server.getThreadPool() instanceof QueuedThreadPool ){ ((QueuedThreadPool) server.getThreadPool()).setMaxIdleTimeMs( 2000 ); } 

setMaxIdleTimeMs() needs to be called after start() , because threadPool is created in start() . However, threads have already been created and are waiting, so they are applied only after all threads are used at least once.

I do not know what else to do, except for some horror, like interrupting all threads or System.exit() .

Any ideas? Is there a good way?

Thanks, Ondra

+6
source share
1 answer

Graceful does not do what you think it does - it allows you to gracefully shut down the server, but it does not allow you to disconnect from inside the servlet.

The problem is as described in the mail list that you contacted - you are trying to stop the server while you are still processing the connection inside the server.

You should try changing the implementation of the servlet:

 // Stop the server. new Thread() { public void run() { try { log.info("Shutting down the server..."); server.stop(); log.info("Server has stopped."); } catch (Exception ex) { log.error("Error when stopping Jetty server: "+ex.getMessage(), ex); } } }.start(); 

In this way, the servlet can complete processing while the server is shutting down and delay the completion process.

+11
source

All Articles