Community
Participate
Working Groups
Build Identifier: jetty-8 M1 When you try to use the Servlet3Continuation wrapper it causes the exception to be thrown. Here's the simple code that I used to test Servlet3Continuation on the Servlet 3.0 enabled server (Tomcat 7.0.4). Servlet3Continuation continuation = new Servlet3Continuation(request); continuation.suspend(); continuation.setTimeout(4000); When timeout hits the Servlet3Continuation calls the asyncEvent.getAsyncContext().dispatch(); method. The call causes the following exception in Tomcat: java.lang.IllegalStateException: Calling [dispatchAsync()] is not valid for a request with Async state [TIMING_OUT] at org.apache.coyote.AsyncStateMachine.asyncDispatch(AsyncStateMachine.java:220) at org.apache.coyote.http11.Http11NioProcessor.actionInternal(Http11NioProcessor.java:672) at org.apache.coyote.http11.AbstractHttp11Processor.action(AbstractHttp11Processor.java:937) at org.apache.coyote.Request.action(Request.java:348) at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:173) at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:135) at org.apache.catalina.core.AsyncContextImpl.dispatch(AsyncContextImpl.java:130) at org.eclipse.jetty.continuation.Servlet3Continuation$1.onTimeout(Servlet3Continuation.java:48) at org.apache.catalina.core.AsyncListenerWrapper.fireOnTimeout(AsyncListenerWrapper.java:45) at org.apache.catalina.core.AsyncContextImpl.timeout(AsyncContextImpl.java:109) at org.apache.catalina.connector.CoyoteAdapter.asyncDispatch(CoyoteAdapter.java:270) at org.apache.coyote.http11.Http11NioProcessor.asyncDispatch(Http11NioProcessor.java:232) at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.event(Http11NioProtocol.java:305) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1526) at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) at java.lang.Thread.run(Thread.java:619) I'm not quite sure if it is a Jetty's or Tomcat's bug. Reproducible: Always Steps to Reproduce: 1. Create a web application with a single Servlet: public class SnowServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Servlet3Continuation continuation = new Servlet3Continuation(request); continuation.suspend(); continuation.setTimeout(4000); } 2. Launch in Tomcat 7 (should run with protocol="org.apache.coyote.http11.Http11NioProtocol" and <async-enabled>true</async-enabled> in servlet description block in web.xml 3. Invoke the servlet in the browser and look at in the console (or in the tomcat's log)
I'm 99% sure this is a tomcat bug. onTimeout calls should be able to call dispatch, from the servlet 3.0 spec: In the event that an asynchronous operation times out, the container must run through the following steps: ■ Invoke the AsyncListener.onTimeout method on all the AsyncListener instances registered with the ServletRequest on which the asynchronous operation was initiated. ■ If none of the listeners called AsyncContext.complete() or any of the AsyncContext.dispatch methods, perform an error dispatch with a status code equal to HttpServletResponse.SC_INTERNAL_SERVER_ERROR. If no matching error page was found, or the error page did not call AsyncContext.complete() or any of the AsyncContext.dispatch methods, the container MUST call AsyncContext.complete(). So this implies that a timeout request can call dispatch. cheers PS. you should probably not create continuations directly, but instead use the ContinuationSupport class to do tht.