Bug 63964 - Null returned when opening resource URL stream
Summary: Null returned when opening resource URL stream
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 9
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 9.0.29
Hardware: PC All
: P2 major (vote)
Target Milestone: -----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-11-26 13:43 UTC by Ján Michalica
Modified: 2019-11-26 18:54 UTC (History)
0 users



Attachments
Sample project to reproduce the issue (3.45 KB, application/zip)
2019-11-26 13:43 UTC, Ján Michalica
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Ján Michalica 2019-11-26 13:43:47 UTC
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.
Comment 1 Remy Maucherat 2019-11-26 15:10:41 UTC
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.
Comment 2 Mark Thomas 2019-11-26 16:33:57 UTC
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.
Comment 3 Mark Thomas 2019-11-26 18:54:21 UTC
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.