Relates :
|
|
Relates :
|
|
Relates :
|
The issue is a timing window in the JDK code (java.net.URL class), it was introduced sometime after JDK 8 (just diff the URL class source code between JDK8 and JDK 11 to see the difference there) what is happening is that: - one thread is setting the factory (URL.setURLStreamHandlerFactory, has the lock, and clears the handlers map) - another thread simultaneously is in URL.getURLStreamHandler, gets to the point where it waits for the lock as the factory is being setup, when it resumes it uses the JDK handler In the JDK 11 URL.getURLStreamHandler code we see that once it gets the lock (after the factory was set in the other thread and releases it), if the handler was null at that point it will get a JDK handler and that will also end up in the handlers map as well...: (the get URL thread is waiting here with a null for handler, after the set factory thread gives up the lock this proceeds to use the default handler when it should check if a factory was set to try using that first) synchronized (streamHandlerLock) { if (handler == null) { // Try the built-in protocol handler handler =defaultFactory.createURLStreamHandler(protocol); } else { URLStreamHandler handler2 = null; This is not an issue in JDK 8 (The JDK 8 code for URL did check for a factory there after getting the lock...)
|