Created attachment 36902 [details] Sample project to reproduce the issue When opening web app resource's URL for reading, null is returned if the URL was obtained in a specific way. See attached sample project: URL dir = servletContext.getResource("/WEB-INF/dir/"); URL file = new URL(dir, "file"); InputStream in = file.openStream(); // null returned even if the "/WEB-INF/dir/file" exists. The issue seems to be in CachedResourceURLStreamHandler, where opening the URLConnection ignores provided URL: @Override protected URLConnection openConnection(URL u) throws IOException { return new CachedResourceURLConnection(resourceURL, root, webAppPath, usesClassLoaderResources); } The "resourceUrl" points to the parent directory, so null is answered as the input stream.
Given this and other posts in the user list, I think there's an issue with the URL resolution that was added. Trying to have a full implementation may lead up to the Tomcat 7 resources complexity it seems (except without JNDI and the custom protocol, but this strategy had its own benefits if you want a full implementation that worked in all cases), because next time we'll have someone asking "oh and if I do servletContext.getResource("/WEB-INF/dir/").toString() + "/myPath" I have an inconsistent result", which is basically what people spent months spamming me about during the Tomcat 5 days. Maybe the URL stream handler should be reverted and the JSP recompilation "issue" (a 100% brain dead use case) and other similar possible inconsistencies should be documented as wontfix instead of venturing again into that nest of spiders.
Just to join up the dots as I suspect we'll be pointing lots of folks to this bug. The currently suspect commits are (9.0.x, 8.5.x. has similar commits): https://github.com/apache/tomcat/commit/03e7bc8487cb706adf1f56586948a7762dd42d14 https://github.com/apache/tomcat/commit/b12f3b1bf09ecbd7d3633ac4dc29d6b18a37c2ab These were intended to address this bug from the users list: https://tomcat.markmail.org/thread/pqiqbzqbdmzz464j I share Rémy's lack of enthusiasm for a full 7.0.x style solution to this but I do want to look to see if there is a way to make the current solution sufficiently robust rather than revert the fix.
Fixed in: - master for 9.0.30 onwards - 8.5.x for 8.5.50 onwards 7.0.x was not affected. Generally, the solution I am aiming for is not as comprehensive as the 7.0.x custom handler solution. The intention is if you use a URL obtained from WebResourceRoot then what you see will always be consistent (i.e. if will use the cache if present). If you obtain a URL directly or manipulate a URL obtained from WebResoureRoot you are accessing the resource directly, bypassing the cache and may see inconsistent results.