Java – jetty: stopping programmatically causes “1 thread cannot be stopped”
I have an embedded jetty 6.1 26 examples
@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 send a request, jetty doesn't stop - a thread has been hanging with this Org. On the line of wait() mortbay. thread. In queuedthreadpool:
// 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 will block for a minute and then turn off I added graceful shutdown, which should allow me to shut down the server from the servlet; However, it cannot be seen from the log
I solved this:
Server server = new Server( PORT ); server.setGracefulShutdown( 3000 ); server.setStopAtShutdown(true); ... server.start(); if( server.getThreadPool() instanceof QueuedThreadPool ){ ((QueuedThreadPool) server.getThreadPool()).setMaxIdleTimeMs( 2000 ); }
You need to call setMaxIdleTimeMs () after start (), because threadPool. is created in start (). However, threads have been created and wait, so it only applies after all threads have been used at least once
Except interrupt all threads or system I don't know what else to do besides some terrible things like exit ()
Any ideas? Is there a good way?
Solution
Graceful doesn't do what you want - it allows the server to shut down normally, but it doesn't allow you to shut down from within the servlet
The problem is described in the mailing list post you linked to - you are trying to stop the server while you are still processing the connection inside the server
You should try to change the servlet implementation to:
// 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 when the server shuts down without blocking the shutdown process