JDK-8135232 : sun.awt.AppContext is null when setting SecurityManager null in JavaWS
  • Type: Bug
  • Component: deploy
  • Sub-Component: webstart
  • Affected Version: 7u25,8
  • Priority: P3
  • Status: Resolved
  • Resolution: Won't Fix
  • OS: windows_7
  • CPU: x86_64
  • Submitted: 2015-07-02
  • Updated: 2017-09-19
  • Resolved: 2017-09-19
Related Reports
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]

A DESCRIPTION OF THE PROBLEM :
sun.awt.AppContext is null when changing from com.sun.javaws.security.JavaWebStartSecurity to System.setSecurityManager(null).

This problem started with 7u25. It only appears when using java web start with RMI and setting SecurityManager null.

Scenario: 
Two separate jnlp apps Producer (P) and Consumer (C) are started from a webserver.
All exceptions appear in C.
Both P and C set SecurityManager to null.

Exceptions 1) and 2) are inside a rmi thread in C where P notifies C about a change. And when C tries to do stuff with the Swing GUI the exceptions are thrown.

Exception 3) is not in an RMI thread. C calls a method inside P using RMI and the exception is shown in C but the NPE happens inside P before the method is reached. My guess is because com.sun.deploy.uitoolkit.ToolkitStore.get().getAppContext() is used which returns null due to same bug as with exceptions 1) and 2).


###manually collected information: 

###for exceptions 1) and 2):

###no javaws 8u45
javaplugin.version=null
javawebstart.version=null
javafx.version=null
SecurityManager is already null
current: java.lang.ThreadGroup[name=RMI Runtime,maxpri=10]
map sun.awt.AppContext.threadGroup2appContext:
java.lang.ThreadGroup@34f5090e java.lang.ThreadGroup[name=system,maxpri=10]	sun.awt.AppContext@2d722995 sun.awt.AppContext[threadGroup=system]
java.lang.ThreadGroup@20d3d15a java.lang.ThreadGroup[name=main,maxpri=10]	sun.awt.AppContext@2d722995 sun.awt.AppContext[threadGroup=system]

###with javaws 7u17 
javaplugin.version=null
javawebstart.version=javaws-10.17.2.02
javafx.version=null
SecurityManager changed from class com.sun.javaws.security.JavaWebStartSecurity to null
current: java.lang.ThreadGroup[name=RMI Runtime,maxpri=10]
map sun.awt.AppContext.threadGroup2appContext:
java.lang.ThreadGroup@d68561 java.lang.ThreadGroup[name=javawsApplicationThreadGroup,maxpri=10]	sun.awt.AppContext@12cdd20 sun.awt.AppContext[threadGroup=system]
java.lang.ThreadGroup@f93ee4 java.lang.ThreadGroup[name=main,maxpri=10]	sun.awt.AppContext@12cdd20 sun.awt.AppContext[threadGroup=system]
java.lang.ThreadGroup@30db0e java.lang.ThreadGroup[name=RMI Runtime,maxpri=10]	sun.awt.AppContext@12cdd20 sun.awt.AppContext[threadGroup=system]
java.lang.ThreadGroup@5ed853 java.lang.ThreadGroup[name=javawsSecurityThreadGroup,maxpri=10]	sun.awt.AppContext@154c08a sun.awt.AppContext[threadGroup=javawsSecurityThreadGroup]
java.lang.ThreadGroup@e4e358 java.lang.ThreadGroup[name=system,maxpri=10]	sun.awt.AppContext@12cdd20 sun.awt.AppContext[threadGroup=system]

###with javaws 8u45 
javaplugin.version=null
javawebstart.version=javaws-11.45.2.15
javafx.version=null
SecurityManager changed from class com.sun.javaws.security.JavaWebStartSecurity to null
current: java.lang.ThreadGroup[name=RMI Runtime,maxpri=10]
map sun.awt.AppContext.threadGroup2appContext:
java.lang.ThreadGroup@4ce2d4a7 java.lang.ThreadGroup[name=javawsApplicationThreadGroup,maxpri=10]	sun.awt.AppContext@2a5c0d3d sun.awt.AppContext[threadGroup=javawsApplicationThreadGroup]
java.lang.ThreadGroup@78308db1 java.lang.ThreadGroup[name=main,maxpri=10]	sun.awt.AppContext@63ae84a3 sun.awt.AppContext[threadGroup=main]
java.lang.ThreadGroup@4fcd8895 java.lang.ThreadGroup[name=javawsSecurityThreadGroup,maxpri=10]	sun.awt.AppContext@7390d80a sun.awt.AppContext[threadGroup=javawsSecurityThreadGroup]

###for exception 3)

###with javaws 8u45 
java.runtime.version=1.8.0_45-b15
javaplugin.version=null
javawebstart.version=javaws-11.45.2.15
javafx.version=null
SecurityManager changed from class com.sun.javaws.security.JavaWebStartSecurity to null
current ThreadGroup: java.lang.ThreadGroup[name=javawsApplicationThreadGroup,maxpri=10]
map sun.awt.AppContext.threadGroup2appContext:
java.lang.ThreadGroup@5334a1e4 java.lang.ThreadGroup[name=javawsSecurityThreadGroup,maxpri=10]	sun.awt.AppContext@35d3d09c sun.awt.AppContext[threadGroup=javawsSecurityThreadGroup]
java.lang.ThreadGroup@53327d87 java.lang.ThreadGroup[name=javawsApplicationThreadGroup,maxpri=10]	sun.awt.AppContext@105e38e9 sun.awt.AppContext[threadGroup=javawsApplicationThreadGroup]
java.lang.ThreadGroup@3fee733d java.lang.ThreadGroup[name=main,maxpri=10]	sun.awt.AppContext@182dace7 sun.awt.AppContext[threadGroup=main]


ADDITIONAL REGRESSION INFORMATION: 
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)

last time it worked in 7u21. 

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Change SecurityManager from class from com.sun.javaws.security.JavaWebStartSecurity to null.

In an RMI Thread that exists inside the JVM where SecurityManager was set to null, call SwingUtillities.invokeLater

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
no NPE
ACTUAL -
NPE(s)

ERROR MESSAGES/STACK TRACES THAT OCCUR :
1) SwingUtillities.invokeLater is called
java.lang.NullPointerException
        at sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown Source)
        at sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown Source)
        at sun.awt.SunToolkit.getSystemEventQueueImpl(Unknown Source)
        at java.awt.Toolkit.getEventQueue(Unknown Source)
        at java.awt.EventQueue.invokeLater(Unknown Source)
        at javax.swing.SwingUtilities.invokeLater(Unknown Source)
        at java8err.Globals.checkSunAwtAppContext(Globals.java:122)
        at java8err.rmi.ConsumerServiceImp.consume(ConsumerServiceImp.java:15)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
        at java.lang.reflect.Method.invoke(Unknown Source)
        at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source)
        at sun.rmi.transport.Transport$1.run(Unknown Source)
        at sun.rmi.transport.Transport$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.Transport.serviceCall(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$254(Unknown Source)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$18/195353247.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
        at java.lang.Thread.run(Unknown Source)

2) 
java.lang.NullPointerException: null
        at javax.swing.SwingUtilities.appContextGet(Unknown Source) ~[na:1.8.0_45]
        at javax.swing.JComponent.getDefaultLocale(Unknown Source) ~[na:1.8.0_45]
        at javax.swing.JComponent.<init>(Unknown Source) ~[na:1.8.0_45]
        at javax.swing.JPanel.<init>(Unknown Source) ~[na:1.8.0_45]
        at javax.swing.JPanel.<init>(Unknown Source) ~[na:1.8.0_45]
        at javax.swing.JPanel.<init>(Unknown Source) ~[na:1.8.0_45]
        ... 

3) 
org.springframework.remoting.RemoteInvocationFailureException: Invocation of method [public abstract ....accumulateProductionSettings(....)] failed in RMI service [rmi://....:64099/MachineData]; nested exception is java.lang.NullPointerException
        at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:358) ~[spring-context-4.1.2.RELEASE.jar:4.1.2.RELEASE]
        at org.springframework.remoting.rmi.RmiClientInterceptor.invoke(RmiClientInterceptor.java:260) ~[spring-context-4.1.2.RELEASE.jar:4.1.2.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.1.2.RELEASE.jar:4.1.2.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207) ~[spring-aop-4.1.2.RELEASE.jar:4.1.2.RELEASE]
        at com.sun.proxy.$Proxy26.accumulateProductionSettings(Unknown Source) ~[na:na]
        ... code here simply calls a method of another service
Caused by: java.lang.NullPointerException: null
        at com.sun.jnlp.JNLPClassLoader.getPermissions(Unknown Source) ~[na:na]
        at java.security.SecureClassLoader.getProtectionDomain(Unknown Source) ~[na:1.8.0_45]
        at java.security.SecureClassLoader.defineClass(Unknown Source) ~[na:1.8.0_45]
        at java.net.URLClassLoader.defineClass(Unknown Source) ~[na:1.8.0_45]
        at java.net.URLClassLoader.access$100(Unknown Source) ~[na:1.8.0_45]
        at java.net.URLClassLoader$1.run(Unknown Source) ~[na:1.8.0_45]
        at java.net.URLClassLoader$1.run(Unknown Source) ~[na:1.8.0_45]
        at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_45]
        at java.net.URLClassLoader.findClass(Unknown Source) ~[na:1.8.0_45]
        at com.sun.jnlp.JNLPClassLoader.findClass(Unknown Source) ~[na:na]
        at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_45]
        at java.lang.ClassLoader.loadClass(Unknown Source) ~[na:1.8.0_45]
        at java.lang.Class.getDeclaredFields0(Native Method) ~[na:1.8.0_45]
        at java.lang.Class.privateGetDeclaredFields(Unknown Source) ~[na:1.8.0_45]
        at java.lang.Class.getDeclaredFields(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectStreamClass.getDefaultSerialFields(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectStreamClass.getSerialFields(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectStreamClass.access$800(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectStreamClass$2.run(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectStreamClass$2.run(Unknown Source) ~[na:1.8.0_45]
        at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_45]
        at java.io.ObjectStreamClass.<init>(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectStreamClass.lookup(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectStreamClass.initNonProxy(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readNonProxyDesc(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readClassDesc(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readArray(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.defaultReadFields(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readSerialData(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readOrdinaryObject(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readObject0(Unknown Source) ~[na:1.8.0_45]
        at java.io.ObjectInputStream.readObject(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.server.UnicastRef.unmarshalValue(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.transport.Transport$1.run(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.transport.Transport$1.run(Unknown Source) ~[na:1.8.0_45]
        at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_45]
        at sun.rmi.transport.Transport.serviceCall(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$254(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler$$Lambda$19/1922547073.run(Unknown Source) ~[na:na]
        at java.security.AccessController.doPrivileged(Native Method) ~[na:1.8.0_45]
        at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) ~[na:1.8.0_45]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source) ~[na:1.8.0_45]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) ~[na:1.8.0_45]
        at java.lang.Thread.run(Unknown Source) [na:1.8.0_45]
        at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source) ~[na:1.8.0_45]
        at sun.rmi.server.UnicastRef.invoke(Unknown Source) ~[na:1.8.0_45]
        at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source) ~[na:1.8.0_45]
        at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source) ~[na:1.8.0_45]
        at com.sun.proxy.$Proxy7.invoke(Unknown Source) ~[na:na]
        at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:399) ~[spring-context-4.1.2.RELEASE.jar:4.1.2.RELEASE]
        at org.springframework.remoting.rmi.RmiClientInterceptor.doInvoke(RmiClientInterceptor.java:345) ~[spring-context-4.1.2.RELEASE.jar:4.1.2.RELEASE]
        ... 7 common frames omitted


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
Test case is too complicated to be created as it involves jnlp/java webstart.

But for exceptions 1) and 2) see example project https://github.com/bdt-stru/java8error which generates similar exceptions.

Exception 3) could not be replicated in another project. But fixing 1) and 2) should fix 3) too.

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

CUSTOMER SUBMITTED WORKAROUND :
Current workaround is staying with java < 7u25

Exceptions 1) and 2) can be bypassed by doing the work in another non RMI-Thread.

Exception 3) however cannot be bypassed as it happens before own code is reached.
Comments
As I stated above in 2015, This is caused by security fix JDK-8004584 in 7u25 and JDK8. The wider problem was addressed as JDK-8019274 but only covers cases where there is a non-null security manager. Since a signed webstart app (or applet running alone in a vm) can reset the security manager to null, this problem has existed ever since. Closing as will not fix
19-09-2017

I'm not sure if this still a problem after JDK-8019274 is fixed. Unless there are use cases that user has to set SecurityManager to NULL.
07-04-2016

Please review and see if this has to be addressed for 1602
08-02-2016

This was originally caused by JDK-8004584 fix in 7u25, Originally this caused all RMI Threads to get null returned from AppContext.getAppContext(). Changes were then put in to fix JDK-8019274, but only apply when security manager is installed, hence this bug remains.
02-12-2015

Checked this for 8u60 and 8u66 b18 and could reproduce the exception 1 and 2 as reported. Steps to reproduce: ========================= - Go to test project at: https://github.com/bdt-stru/java8error - run create_keystore.bat to generate a keystore for signing Note: Answer all questions with: y - run: mvn clean verify - run: target\staging\server\bin\run_webserver.bat - Launch a browser session to localhost: http://127.0.0.1:80/ - Ensure Java Console in Java Control Panel is enabled to "Show Console" - Start Rmi Applications in the order they are listed on the webpage ( jnlp/index.html ) https://github.com/bdt-stru/java8error Above generates NPE: java.lang.NullPointerException at sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown Source) at sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown Source) at sun.awt.SunToolkit.getSystemEventQueueImpl(Unknown Source) at java.awt.Toolkit.getEventQueue(Unknown Source) at java.awt.EventQueue.invokeLater(Unknown Source) at javax.swing.SwingUtilities.invokeLater(Unknown Source) at java8err.Globals.checkSunAwtAppContext(Globals.java:122)
01-12-2015