JDK-7177996 : new URL("file://foo.com/bar").openConnection() blocks class loading for more than 20 sec on Windows
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.net
  • Affected Version: 7u4
  • Priority: P3
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows
  • CPU: generic
  • Submitted: 2012-06-19
  • Updated: 2022-01-19
  • Resolved: 2022-01-19
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbdResolved
Related Reports
Duplicate :  
Relates :  
Description
If a program calls java.net.URL.openConnection for a URL of the form "file://foo.com/bar", the call hangs and blocks class loading in other threads for more than 20 seconds on Windows.

To reproduce, run the following test program:

public class OpenConnectionTest {
    
    public static void main(String[] args) throws IOException {
        new Thread(new Runnable() {
            @Override public void run() {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException ex) {
                    throw new AssertionError(ex);
                }
                tryLoadOtherClass();
            }
        }).start();
        System.out.println("openConnection enter");
        new URL("file://foo.com/bar").openConnection();
        System.out.println("openConnection exit");
    }
    
    private static void tryLoadOtherClass() {
        OtherClass.class.getName();
        System.out.println("OtherClass loaded");
    }
}

class OtherClass {
}

The program will print "openConnection enter", wait for more than 20 seconds, and then print "openConnection exit" immediately followed by "OtherClass loaded". The problem is, not only does URL.openConnection take more than 20 seconds to complete, but it also blocks class loading in another thread for the whole duration of the URL.openConnection call.

The thread dump taken while the test program is in URL.openConnection is as follows:

Full thread dump Java HotSpot(TM) Client VM (23.0-b21 mixed mode, sharing):

"Thread-0" prio=6 tid=0x04988c00 nid=0x1318 waiting for monitor entry [0x048fe000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at java.net.URLStreamHandler.getHostAddress(Unknown Source)
        - waiting to lock <0x24377e18> (a sun.net.www.protocol.file.Handler)
        at java.net.URLStreamHandler.hostsEqual(Unknown Source)
        at sun.net.www.protocol.file.Handler.hostsEqual(Unknown Source)
        at java.net.URLStreamHandler.sameFile(Unknown Source)
        at java.net.URLStreamHandler.equals(Unknown Source)
        at java.net.URL.equals(Unknown Source)
        at java.security.CodeSource.equals(Unknown Source)
        at java.util.HashMap.get(Unknown Source)
        at java.security.SecureClassLoader.getProtectionDomain(Unknown Source)
        - locked <0x2437c300> (a java.util.HashMap)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        - locked <0x24398488> (a java.lang.Object)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at OpenConnectionTest.tryLoadOtherClass(OpenConnectionTest.java:23)
        at OpenConnectionTest.access$000(OpenConnectionTest.java:4)
        at OpenConnectionTest$1.run(OpenConnectionTest.java:14)
        at java.lang.Thread.run(Unknown Source)

...

"main" prio=6 tid=0x00aeb800 nid=0x784 runnable [0x00c2f000]
   java.lang.Thread.State: RUNNABLE
        at java.io.WinNTFileSystem.getBooleanAttributes(Native Method)
        at java.io.File.exists(Unknown Source)
        at sun.net.www.protocol.file.Handler.openConnection(Unknown Source)
        - locked <0x24377e18> (a sun.net.www.protocol.file.Handler)
        at sun.net.www.protocol.file.Handler.openConnection(Unknown Source)
        - locked <0x24377e18> (a sun.net.www.protocol.file.Handler)
        at java.net.URL.openConnection(Unknown Source)
        at OpenConnectionTest.main(OpenConnectionTest.java:18)

It looks like URL.openConnection hangs because the URL turns out to represent a Windows network path, thus causing significant delays during the call to File.exists. The delay is probably inferred by the operating system and yet alone does not constitute a problem. The real problem is, for the entire duration of the call, URL.openConnection turns out to lock an object monitor (<0x24377e18> in the above thread dump) that blocks all class loading taking place on other threads.

The problem seems to be related to 7146776. The problem is a root cause for the following JavaFX and NetBeans issues:

    http://javafx-jira.kenai.com/browse/RT-22458
    http://netbeans.org/bugzilla/show_bug.cgi?id=213759

Comments
The problem no longer happens after JDK-7146776; local testing shows: openConnection enter OtherClass loaded openConnection exit the second line appears almost immediately.
19-01-2022

EVALUATION Accepting, further investigation is needed to see if the synchronization is really needed ( as suggested by CR 7146776 ).
21-06-2012