Observations: URLClassPath and HTTP request

Eirik Bjørsnøs eirbjo at gmail.com
Sun Feb 22 14:29:32 UTC 2026


Hi,

While working on JDK-8378398 / https://github.com/openjdk/jdk/pull/29864, I
made some observations about URLClassLoader / URLClassPath and the way it
handles HTTP redirects.

Let's say that user code does:

loader = new URLClassLoader(new URL[] {new URL("http://localhost/"});
loader.getResourceAsStream("image.gif");

This will internally call URLClassPath::findResource, which will do a HEAD
to check if the resource exists. If the server responds with 301 Location:
/target.gif, then HttpURLConnection will follow this redirect and do
another HEAD for /target.gif.

Then, URLClassLoader will call openConnection and getInputStream on the
URL. The HttpURLConnection does a GET for /image.gif and the server will
respond with the same 301. HttpURLConnection does another GET, this time
for /target.gif.

I found two observations interesting and somewhat unexpected:

1) getResourceAsStream calls HEAD before calling GET. I don't quite
understand why this is necessary, it seems it would be better to do the GET
unconditionally to save a request.

2) getResourceAsStream follows redirects for the HEAD request, but then
completely forgets that this URL was just redirected and immediately
performs a GET against the original URL, not the permanently redirected
one. This seems wasteful.

To summarize, the code above currently produces the following requests:

HEAD /image.gif
HEAD /target.gif
GET /image.gif
GET /target.gif

While my intuition tells me the following should be sufficient:

GET /image.gif
GET /target.gif

Just wanted to share these observations, not sure if anything should be
done to improve the current state of affairs.

Cheers,
Eirik.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/net-dev/attachments/20260222/3351ab48/attachment-0001.htm>


More information about the net-dev mailing list