Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8340993

Opening file URL with non existing host blocks concurrent file URL opening

XMLWordPrintable

    • generic
    • windows

      ADDITIONAL SYSTEM INFORMATION :
      Windows
      Java versions < 19

      A DESCRIPTION OF THE PROBLEM :
      On Windows opening file URL with non existing host ("file://&lt;non existing host>/...") blocks all concurrent unrelated file URL open actions.

      A practical example for the problem would be one thread parsing HTML with file URLs (and trying to reach them) that totally blocks other unrelated threads which try to read other file URLs or read a JAR content.

      Cause of the problem is redundant synchronization in the class sun.net.www.protocol.file.Handler. Synchroinzation was removed in Java 19, see https://bugs.openjdk.org/browse/JDK-8278263. JDK-8278263 should be backported to the Java 8 (and other LTS versions).

      Note: the problem is analogous but not the same as fixed in https://bugs.openjdk.org/browse/JDK-7177996, https://bugs.openjdk.org/browse/JDK-7146776

      JDK-8278263 should be backported to the Java 8 (and other LTS versions).

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run provided test code

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Expected that
      "openConnection 2 enter"
      is immediately followed by
      "openConnection 2 exit"

      ACTUAL -
      Blocking occurs of the second connection. Output is:
      "openConnection enter"
      "openConnection 2 enter"
      <HERE HAPPENS 20 sec. DELAY - openConnection 2 is blocked>
      "openConnection exit"
      "openConnection 2 exit"

      Blocking occurs on the monitor of the method sun.net.www.protocol.file.Handler#openConnection().
      Relevant stack dump (note that java.io.WinNTFileSystem.getBooleanAttributes() takes 20 secs. for non existing host):

      "main" #1 prio=5 os_prio=0 tid=0x00000000025dd800 nid=0x9f50 runnable [0x00000000026df000]
         java.lang.Thread.State: RUNNABLE
              at java.io.WinNTFileSystem.getBooleanAttributes(Native Method)
              at java.io.File.exists(File.java:819)
              at sun.net.www.protocol.file.Handler.openConnection(Handler.java:97)
              - locked <0x0000000716e48878> (a sun.net.www.protocol.file.Handler)
              at sun.net.www.protocol.file.Handler.openConnection(Handler.java:72)
              - locked <0x0000000716e48878> (a sun.net.www.protocol.file.Handler)
              at java.net.URL.openConnection(URL.java:979)
              at TestJvmFileHandler.main(TestJvmFileHandler.java:26)

      "Thread-0" #19 prio=5 os_prio=0 tid=0x000000002a9b5000 nid=0xae60 waiting for monitor entry [0x000000002b0df000]
         java.lang.Thread.State: BLOCKED (on object monitor)
              at sun.net.www.protocol.file.Handler.openConnection(Handler.java:72)
              - waiting to lock <0x0000000716e48878> (a sun.net.www.protocol.file.Handler)
              at java.net.URL.openConnection(URL.java:979)
              at TestJvmFileHandler.lambda$0(TestJvmFileHandler.java:15)
              at TestJvmFileHandler$$Lambda$1/531885035.run(Unknown Source)
              at java.lang.Thread.run(Thread.java:748)


      ---------- BEGIN SOURCE ----------
      public class TestJvmFileHandler {

          public static void main(String[] args) throws Exception {

              new Thread(() -> {
                  try {
                      Thread.sleep(1000);
                  } catch (InterruptedException ex) {
                      throw new IllegalStateException(ex);
                  }
                  System.out.println("openConnection 2 enter");
                  try {
                      new URL("file:///c:/Temp/test.jar").openConnection();
                      // or new URL("jar:file:///c:/Temp/test.jar!/META-INF/MANIFEST.MF").openConnection();
                  } catch (Exception ex) {
                      ex.printStackTrace();
                  }
                  System.out.println("openConnection 2 exit");
              }).start();

              try {
                  System.out.println("openConnection enter");

                  new URL("file://foo.com/bar").openConnection();
                  System.out.println("openConnection exit");
              } catch (Exception ex) {
                  ex.printStackTrace();
              }
          }

      }
      ---------- END SOURCE ----------

      FREQUENCY : always


            rpallath Rajendrakumar Pallath
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Created:
              Updated: