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

Slow opening of the JFileChooser when desktop contains broken lnk file

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      Present on 8u202, and 11.0.3

      A DESCRIPTION OF THE PROBLEM :
      The fix applied to 8213583 to not show the Windows popup does not set a timeout for the resolve check. As per the IShellLinkW::Resolve documentation (https://docs.microsoft.com/en-us/windows/win32/api/shobjidl_core/nf-shobjidl_core-ishelllinkw-resolve) states:

      SLR_NO_UI (0x0001)
      0x0001. Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set, the high-order word of fFlags can be set to a time-out value that specifies the maximum amount of time to be spent resolving the link. The function returns if the link cannot be resolved within the time-out duration. If the high-order word is set to zero, the time-out duration will be set to the default value of 3,000 milliseconds (3 seconds). To specify a value, set the high word of fFlags to the desired time-out duration, in milliseconds.

      SLR_NO_UI was set to fix 8213583, committed in http://hg.openjdk.java.net/jdk/jdk/diff/c8071863df80/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp

      Suggest to set a timeout that is shorter than 3s to make opening the JFileBrowser faster. Usually a couple of milliseconds should be enough, a bit more if .lnk files pointing to network shares should be covered.

      As an example of where to fix this, to set the timeout to 100ms, apply the following patch:
      ---
      --- a/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp
      +++ b/src/java.desktop/windows/native/libawt/windows/ShellFolder2.cpp
      @@ -745,7 +745,7 @@ JNIEXPORT jlong JNICALL Java_sun_awt_shell_Win32ShellFolder2_getLinkLocation
                   hres = ppf->Load(wstr, STGM_READ);
                   if (SUCCEEDED(hres)) {
                       if (resolve) {
      - hres = psl->Resolve(NULL, SLR_NO_UI);
      + hres = psl->Resolve(NULL, 100 << 16 | SLR_NO_UI);
                           // Ignore failure
                       }
                       pidl = (LPITEMIDLIST)NULL;
      ---

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create one or more broken links on the desktop.

      E.g run the following powershell script from the desktop:
      $shell = New-Object -ComObject WScript.Shell $shortcut = $shell.CreateShortcut("broken.lnk")
      $shortcut.TargetPath = "svn.exe"
      $shortcut.IconLocation = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe,0"
      $shortcut.Save()

      This creates broken.lnk poiting to svn.exe on the desktop (svn.exe should _not_ be present)

      Open a JFileChooser dialog, similar to 8213583, observe slow to open.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Quick opening of the file dialog
      ACTUAL -
      Opening the dialog hangs for some time (proportional to amount of broken links). The call to IShellLinkW::Resolve happens multiple times per file, so the delay is 3s * 3 (ish)

      ---------- BEGIN SOURCE ----------

      /////////////////////////////////////
      //
      // NOTE:
      // There must be a broken shortcut in the Windows desktop before running this program.
      //

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

              // Creates a temporary security policy
              final File tempPolicyFile = File.createTempFile("broken-links-bug-", ".policy");
              tempPolicyFile.deleteOnExit();
              try (final PrintStream policyStream = new PrintStream(new FileOutputStream(tempPolicyFile))) {
                  policyStream.println("grant { permission java.security.AllPermission; };");
              }
              System.setProperty("java.security.policy", tempPolicyFile.getAbsolutePath());

              // Trigger the problem
              System.setSecurityManager(new SecurityManager());
              JFileChooser chooser = new JFileChooser();

              chooser.showDialog(null, "Open"); // not really needed
          }
      }

      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Remove any broken links

      FREQUENCY : always


            pnarayanaswa Praveen Narayanaswamy
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: