JDK-8164617 : sun.awt.AppContext null in javafx java web start application with SSL/Client Certs Required
  • Type: Bug
  • Component: deploy
  • Sub-Component: webstart
  • Affected Version: 8u77
  • Priority: P3
  • Status: Closed
  • Resolution: Cannot Reproduce
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2016-04-11
  • Updated: 2017-07-25
  • Resolved: 2017-07-25
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.
JDK 8
8-poolResolved
Related Reports
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_77"
Java(TM) SE Runtime Environment (build 1.8.0_77-b03)
Java HotSpot(TM) 64-Bit Server VM (build 25.77-b03, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

EXTRA RELEVANT SYSTEM CONFIGURATION :
Java Web Start application served by IIS 7.5 on Windows Server 2012 with SSL enabled and "Client Certificate Required".
On client, multiple candidate client certificates are present from which I am prompted to choose.

A DESCRIPTION OF THE PROBLEM :
I have a java web start javafx application that is downloaded from a server for which https is enabled and client certificates are required. When I launch the application from a host on which there is a single client certificate available in my personal certificate store, the application launches and runs properly.

In the event I am launching the application on a host for which there are 2 or more client certificates, the first jp2launcher.exe prompts me to choose a certificate, which I expect, since the process needs the certificate to successfully download the application jar files. Then, jp2launcher.exe runs again (which is expected, given javafx results in jp2launcher.exe relaunch), and prompts me to choose a certificate, checking the viability of the cache. In this situation, however, my application starts, but throws some unexpected exceptions, each of which I have traced back to AppContext.getAppContext() returning null. Thus calls in my application like Desktop.getDesktop() and IIORegistry.getDefaultInstance() result in NullPointerException being thrown.

I then reproduced the problem in the "hello world" application, and in the javafx application constructor AND init methods, I printed the AppContext information to which I had access.

When the client has only one candidate certificate, and thus is not asked to choose a certificate at the time the application is downloaded & started, the debug information is this:

LORI: RedactionTool constructor; AppContext.getAppContext is returning a value as expected.
LORI: RedactionTool constructor; the appcontexts set is empty
LORI: RedactionTool.init; AppContext.getAppContext is returning a value as expected.
LORI: RedactionTool.init; the appcontexts set has 1 elements
LORI: RedactionTool.init; app Context sun.awt.AppContext[threadGroup=main]

When the client is asked to choose a certificate, the debug output indicates this:

LORI: RedactionTool constructor; AppContext.getAppContext is returning null, trouble is brewing
LORI: RedactionTool constructor; the appcontexts set has 1 elements
LORI: RedactionTool constructor; app Context sun.awt.AppContext[threadGroup=Plugin Thread Group]
LORI: RedactionTool.init; AppContext.getAppContext is returning null, trouble is brewing
LORI: RedactionTool.init; the appcontexts set has 1 elements
LORI: RedactionTool.init; app Context sun.awt.AppContext[threadGroup=Plugin Thread Group]

So, in the event the user is prompted to select from among client certificates at startup, the AppContext is not properly initialized on the main thread group.  Thus, calls that depend on the AppContext in the main thread group fail unexpectedly with a NullPointerException.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Create a javafx java web start application, configure it to be served by an application server that has SSL configured and is set to require client certificates to be presented.  Attempt to run the application on host as a user that has multiple client certificates from which the user must choose when starting the application.



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Whether I need to choose a certificate or not, I expect the AppContext for the main thread group to be properly initialized.
ACTUAL -
In the event the user is prompted to select from among client certificates at startup, the AppContext is not properly initialized on the main thread group.  Thus, calls that depend on the AppContext in the main thread group fail unexpectedly with a NullPointerException.


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Can be reproduced with javafx hello world example.  I added the following to the javafx application init and constructor to inspect AppContext:

    // app context debugging information 
    private static void reviewAppContextInfo(String caller)
    {
        Set<AppContext> contexts = AppContext.getAppContexts();
        
        if (null == AppContext.getAppContext())
        {
            System.out.println("LORI: " + caller + "; AppContext.getAppContext is returning null, trouble is brewing");
        }
        else
        {
            System.out.println("LORI: " + caller + "; AppContext.getAppContext is returning a value as expected.");
        }
        
        if (contexts.isEmpty())
        {
            System.out.println("LORI: " + caller + "; the appcontexts set is empty");
        }
        else 
        {
           System.out.println("LORI: " + caller + "; the appcontexts set has " + contexts.size() + " elements");
           Iterator<AppContext> e = contexts.iterator();
           int i = 0;
           while (e.hasNext()) 
           {
               i++;
               AppContext a = e.next();
               System.out.println("LORI: " + caller + "; app Context " + a);
           }
        }        
    }
    
    public RedactionTool() {
        super();
        reviewAppContextInfo("RedactionTool constructor");
    }
    
    @Override public void init() throws Exception {
        reviewAppContextInfo("RedactionTool.init");
    }


The following code added to the "handleButtonAction" demonstrates the challenge presented by the AppContext being uninitialized:

    @FXML
    private void handleButtonAction(ActionEvent event) {
        System.out.println("You clicked me!");

        try {
            Desktop d = Desktop.getDesktop();
        } catch (Exception e) {
            StringBuilder sb = new StringBuilder(e.toString());
            for (StackTraceElement ste : e.getStackTrace()) {
                sb.append("\nat ");
                sb.append(ste);
            }
            String trace = sb.toString();

            label.setText("Desktop.getDesktop() threw exception: \n" + trace);
            return;
        }

        label.setText("Desktop.getDesktop() succeeded");

    }

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

CUSTOMER SUBMITTED WORKAROUND :
I have not found any workaround to this situation except to indicate that various aspects of my application will fail in the event that they are prompted to choose form among their available client certificates.

Depending upon the version of the application server, I have found some ways to limit the client's field of acceptable certificates, but there is no guarantee at the moment that I can prevent the prompt for certificate selection.


Comments
No plans to address for JDK 8. If this is a concern, please raise a Oracle Support Case (SR).
25-07-2017

Any information on Alexey's question?
07-03-2017

Attaching the netbeans/maven project which has certificate signed by test CA. The issue seems similar to JDK-8135232 Couldn't confirm the issue due to unresolved dependencies in the test case.
23-08-2016