We have a servlet filter which creates a RequestDispatcher used to forward the request to a servlet: String processingPath = processPath(req.getServletPath()); RequestDispatcher dispatch = request.getRequestDispatcher(processingPath); dispatch.forward(request, response); In Tomcat 8 the forward() fails because the servlet path doesn't match the servlet mapping definition. This only occurs when the context path is "/". We configure our Context in server.xml: <Host name="localhost" appBase="" createDirs="false" unpackWARs="false" autoDeploy="false" deployOnStartup="false"> <Context path="/" ...> ... </Context> </Host> In ApplicationContext.getRequestDispatcher(String path) the context path is prepended to the resource uri: uriCC.append(context.getPath(), 0, context.getPath().length()); Then in Mapper.map() a ContextVersion is retrieved from contextObjectToContextVersionMap and passed to internalMapWrapper(), which tries to remove the context path: int length = contextVersion.path.length(); ... servletPath = pathOffset + length; ... path.setOffset(servletPath); But the path is empty, so the offset is zero, and we end up with an extra "/" at the start of the servlet path. This causes the servlet mapping to not be matched. This is ultimately due to these lines in MapperListener.registerContext(): String contextPath = context.getPath(); if ("/".equals(contextPath)) { contextPath = ""; } mapper.addContextVersion(host.getName(), host, contextPath, context.getWebappVersion(), context, welcomeFiles, resources, wrappers); In earlier Tomcat versions, the same context object was used to get the context path in both ApplicationContext.getRequestDispatcher() and Mapper.map(). In Tomcat 8 ApplicationContext.getRequestDispatcher() uses a StandardContext object (with path="/"), while Mapper.map() uses a ContextVersion object (with path="").
(In reply to tomcatuser2008 from comment #0) > We configure our Context in server.xml: Pretty much always a bad idea. > <Host name="localhost" appBase="" createDirs="false" unpackWARs="false" An empty appBase is asking for trouble. > <Context path="/" ...> This is an invalid path setting. To quote from section 3.5 of the servlet spec: Context Path: The path prefix associated with the ServletContext that this Servlet is a part of. If this context is the "default" context rooted at the base of the Web server's URL name space, this path will be an empty string. Otherwise, if the context is not rooted at the root of the server's name space, the path starts with a / character but does not end with a / character. You need to correct your configuration. The fact that something useful happened in prior versions is an accident.
Context path values of "/" are now logged as invalid and converted to "".
I backported the path checks to Tomcat 7 (r1640351). It will be in 7.0.58 onwards.
For a record: The check and correction of context paths originates from r1080714 in 7.0.12 (3 years ago). Thus the fix was backported to Tomcat 7 as well.
Thanks for your prompt responses. We'll change our config to <Context path="" ...>.