Uploaded image for project: 'NetBeans'
  1. NetBeans
  2. NETBEANS-58

NB IDE or NB Platform freeze on startup (proxy with Negotiate auth)

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Critical
    • Resolution: Information Provided
    • 8.2, 9.0, 11.0
    • None
    • platform - Proxy
    • None
    • Primarily Windows.

    Description

      When any network operation is performed, such as attempting to contact NetBeans Update Center, the application (IDE or Platform) may freeze. Users will typically experience this on startup. It was reported in old bug tracker as bug 248308.

      The problem arises because of the fix JDK folks applied as a consequence of the reported JDK-8032832 bug. This fix wasn't very clever IMO: it puts a lock on the classloader, thus introducing a range of other problems, one of them being that NetNeans IDE or NetBeans Platform will likely freeze on startup when it attempts a network operation. The fact that their fix made things worse (while no doubt fixing the original issue) has been reported as JDK-8068184.

      WHEN DOES IT HAPPEN?

      As the lock is introduced for authentication of type 'Negotiate' it of course only happens if there's a network proxy on the path which uses this type of authentication. Also known as SPNEGO. This form of authentication is in my experience very common in corporate networks, in particular those that base themselves on the Microsoft stack. But a person on Oracle's own internal network, such as a JDK developer, is most likely not exposed to it.

      There's another condition for it to happen: The JRE runtime must be unable to provide 'credentials' (a Kerberos token) to the network proxy on its own. SPNEGO is really designed to be seamless and promptless. Support for it was added in Java 6. But later on Microsoft tightened the desktop security around obtaining the so-called 'session token' and the JDK folks were never able to work around this (unlike the makers of Chrome, FF, Opera, etc). Therefore, in real-life, SPNEGO in the JRE on Windows is no longer promptless: it will be forced to ask the user for credentials, thus negating the idea of SPNEGO. It is the prompting which causes the freeze. SPNEGO on Mac OS X and Linux is most likely working just fine and the bug will never be experienced.

      HOW DO I KNOW IF I'M AFFECTED BY EXACTLY THIS BUG?

      This bug in this ticket is characterized by the fact that you'll always be able to find the following in your thread dump:

         at sun.net.www.protocol.http.NegotiateAuthentication.isSupported(NegotiateAuthentication.java:<lineno>)
              - locked <OBJECTID> (a org.netbeans.ModuleManager$SystemClassLoader)
      
      

      Note that the Ctrl-Break method of obtaining a thread dump is favoured over jstack and other methods.

      WHY DOES IT HAPPEN?

      There will be a lock held on the classloader object when the JRE's registered Authenticator is invoked. If the Authenticator does work on another thread, that other thread has a need for some classloading and the current thread needs to wait for the result of that thread, then bum!, there's a deadlock between the two threads. This means the lock on the classloader will never be released and it will ultimately affect other threads, such as the AWT dispatch thread (aka Swing EDT) which will then also lock. Then you have what the user experiences as a freeze.

      The NB Platform's own Authenticator, NbAuthenticator, does exactly what I described and will thus be triggering the deadlock. More precisely it will happen when NbAuthenticator calls Keyring. Does this mean the NbAuthenticator does something wrong? No, of course it doesn't. The real problem is the lock on the classloader. It is actually virtually impossible to design an Authenticator which doesn't trigger this problem. You cannot predict when classloading is needed. In fact it is very likely to be needed when application is still not "warm", i.e. during startup.

      WORKAROUNDS

      #1
      If on Windows: Setting the following registry key:

      HKLM\System\CurrentControlSet\Control\Lsa\Kerberos\Parameters\allowtgtsessionkey

      to true will allow the JRE to obtain the session key, thus the JDK's HTTP classes will have no need to invoke Authenticator, thus deadlock will not happen. But this registry key only has effect for users who are not local admins and since it is a HKLM such user will need to ask his administrator to do this change. There's probably zero chance in a million that a corporate network administrator will allow this change. After all, Microsoft introduced the tightened security for a reason and the admin will rightly ask why only the JRE needs this and not Chrome, IE, FF, Opera and so on?

      #2
      Convice the JDK folks that they've made a mess of it with this lock. I've pursued this avenue too. I've done that on the JDK security-dev mailing list. I've pointed to similar bug tickets for Eclipse IDE and IDEA and I got the attention of Weijun Wang ("Max") of Oracle who promised he would look at it. But to be honest the JDK people have a lot of other things on their plate and a fix will take some time.
      UPDATE 29-OCT-2017: To be fair to the JDK folks to issue only occurs with NB's own classloaders. So the chance they'll fix it at the JDK end is probably slim.

      Link: http://mail.openjdk.java.net/pipermail/security-dev/2017-August/016267.html

      #3
      Re-design the Authenticator in the Platform. As I cannot change the code in NB itself, I've created a workaround as a plugin. The recipe is described in Comment 44 on the original NB bug ticket. This is really a workaround, not a fix. It will simply give up on attempting to obtain credentials if it discovers that it is likely to be in this deadlock scenario. Thus it leaves the application with no outbound network connectivity but it is still better than the freeze. It also alerts the user to the situation using a bubble notification.

      Links:
      https://bitbucket.org/phansson/netbeansnetworkauthenticator
      https://bitbucket.org/phansson/netbeansnetworkauthenticator/wiki/JDK-8068184%20Workaround

      #4
      It may help to set proxy username/password explicitly in the NB's Options panel. But this is not a solution I recommend. It means you must put your AD password into NetBeans IDE Options. It will of course be static so once your AD password changes then you must remember to change there as well. And for the user to configure this, it requires that he can actually start the IDE or Platform app in the first place ... which is often not the case because of the freeze.

      #5
      Use a JRE prior to 8u20 or prior to 7u76. To most people this workaround is unacceptable.

      CONCLUSION

      IMHO #3 is the most attractive solution for now. It doesn't exclude the user still doing #1 or #4 to get full benefit. The real solution is of course #2.

      .. and the very best solution long term is if JDK would have same support for SPNEGO on Windows as does 'regular' applications such as Chrome, FF, Opera, IE, Edge, etc. Then we wouldn't have the problem in the first place. This has been discussed intensively over the last 7-8 years but there's a somewhat religious tug of war between Sun/Oracle and Microsoft on the matter. The problem can be solved if the JDK would base itself on the Win32 SSPI api in this area, rather than the long-time deprecated Win32 LsaCallAuthenticationPackage API. We are getting slightly off topic here and not appropriate for a bug ticket.

      Attachments

        1. image-2018-04-24-15-57-47-592.png
          9 kB
          Jean-Marc Borer
        2. nb-freeze-dump.txt
          50 kB
          Jean-Marc Borer
        3. netbeans.txt
          108 kB
          Tilman Hausherr
        4. NETBEANS-58-workaround1.diff
          1 kB
          Jan Lahoda

        Issue Links

          Activity

            People

              Unassigned Unassigned
              phansson phansson
              Votes:
              10 Vote for this issue
              Watchers:
              17 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: