users@servlet-spec.java.net

[servlet-spec users] Getting a RequestDispatcher from an async thread

From: Rossen Stoyanchev <rstoyanchev_at_vmware.com>
Date: Tue, 29 May 2012 13:24:12 -0700 (PDT)

Hi-

The Javadoc of ServletRequest.getRequestDispatcher(String) [1] does not explicitly mention any special cases where it should not work. However when called from an async (non-container) thread, the results vary by container. From the ones I've tried it works on Tomcat, Glassfish, and JBoss but on Jetty (8.1.4) the call to ServletRequest.getDispatcher(String) returns null.

The spec mentions that certain featuers such as "the propagation of Security Identity in EJB calls" are only available when dispatching through the AsyncContext and the examples in the Javadoc of AsyncContext.dispatch [2] show forwarding only from a container thread. However, there is no discussion I could find of what can't be done with the request in an async thread. On the contrary, the general impression is it should be possible to continue to use the request and response from the async thread.

To give a little background, consider that most (all?) Web frameworks have a "front controller" that orchestrates processing -- the processing entails some work in Java followed by a forward to some JSP for rendering. In this context, replacing the forward with an AsyncContext.dispatch is not trivial and has wider implications since the dispatch will go through the framework again and through any number of filters as well. Hence the answer to this question is not simply a matter of preference.

Since the spec doesn't define any limitations on using the request and response I would expect they would just work. Hence I'm not sure if Jetty's behavior is expected and in accordance with the spec? Instead of trying more containers I decided to put the question here for clarification.

Thanks,
Rossen

[1] http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getRequestDispatcher(java.lang.String)
[2] http://docs.oracle.com/javaee/6/api/javax/servlet/AsyncContext.html#dispatch()