Bug 59213 - Async dispatch not working after cross-context forward
Summary: Async dispatch not working after cross-context forward
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.0.32
Hardware: PC All
: P2 normal (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2016-03-22 10:11 UTC by Scott Nicklous
Modified: 2016-03-25 16:26 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Scott Nicklous 2016-03-22 10:11:02 UTC
I ran into this problem while working on the Apache Pluto project, which makes use of async features. I boiled it down to come up with two test servlets that are available here:

https://github.com/msnicklous/AsyncDebug

I have reproduced the problem on both Tomcat 8.0.28 and 8.0.32.

Problem description:

Given Servlet1 and Servlet2 running in separate servlet contexts.

Servlet1 contains the following code:

   PrintWriter writer = resp.getWriter(); 
   writer.append("<h3>Async Debug1</h3>"); 
   AsyncContext actx = req.startAsync(req, resp);
   actx.dispatch("/WEB-INF/jsp/debug1.jsp");

When Servlet1 is accessed directly, the header "Async Debug 1" along with the
contents of debug1.jsp is displayed properly.

Servlet2 contains the following code:

   ServletContext ctx1 = req.getServletContext().getContext("/AsyncDebug1");
   RequestDispatcher rd = ctx1.getRequestDispatcher("/Debug");
   rd.forward(req, resp);

Servlet2 performs a cross-context forward to Servlet1. The Servlet2 web module
contains a context.xml file that enables cross-context support.

When Servlet2 is accessed, the header "Async Debug 1" is displayed, but the
contents of debug1.jsp is not displayed. Also, the log contains the following
message:

22-Mar-2016 08:47:58.875 SEVERE [http-apr-8080-exec-2]
org.apache.jasper.servlet.JspServlet.handleMissingResource File
[/WEB-INF/jsp/debug1.jsp] not found

I think this is incorrect behavior. Since Servlet1 initializes the AsyncContext,
this behavior would seen to contradict the Servlet Specification 3.1, page 15
where the description for the AsyncContext#dispatch(String path) method states:
"The given path is interpreted as relative to the ServletContext that
initialized the AsyncContext.". 

Additional info: 

by hacking around, I noticed that changing the Servlet1 dispatch call as follows causes the async dispatch to work even when Servlet1 is
accessed through a cross-context forward:

   actx.dispatch(req.getServletContext(), "/WEB-INF/jsp/debug1.jsp");
   
where 'req' is the HttpServletRequest. 

Thanks for having a look at this!
Comment 1 Remy Maucherat 2016-03-25 16:26:09 UTC
Ok, the dispatch should use the specified wrapped request. The fix will be in 7.0.69, 8.0.34, 8.5.1, and 9M5.