JDK-8202451 : Swing interop fails when run with a security manager with standalone SDK
  • Type: Bug
  • Component: javafx
  • Sub-Component: swing
  • Affected Version: openjfx11
  • Priority: P3
  • Status: Closed
  • Resolution: Won't Fix
  • Submitted: 2018-04-30
  • Updated: 2021-04-15
  • Resolved: 2021-04-15
Related Reports
Blocks :  
Blocks :  
Relates :  
Relates :  
Relates :  
Sub Tasks
JDK-8210622 :  
Description
To reproduce this, run the following test with the standalone FX SDK (using an OpenJDK 10 build as a boot JDK).

$ gradle -PFULL_TEST=true :systemTests:test --tests test.sandbox.SandboxAppTest

The following two test cases will fail:

test.sandbox.SandboxAppTest > testJFXPanelApp FAILED
    junit.framework.AssertionFailedError: test.sandbox.app.JFXPanelApp: Application failed with a security exception
        at test.sandbox.SandboxAppTest.runSandboxedApp(SandboxAppTest.java:85)
        at test.sandbox.SandboxAppTest.runSandboxedApp(SandboxAppTest.java:51)
        at test.sandbox.SandboxAppTest.testJFXPanelApp(SandboxAppTest.java:114)

Here is the exception from the launched application:

java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "accessClassInPackage.sun.java2d")
	at java.base/java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
	at java.base/java.security.AccessController.checkPermission(AccessController.java:895)
	at java.base/java.lang.SecurityManager.checkPermission(SecurityManager.java:335)
	at java.base/java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1311)
	at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:186)
	at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:499)
	at javafx.swing/javafx.embed.swing.JFXPanel.updateComponentSize(JFXPanel.java:573)
	at javafx.swing/javafx.embed.swing.JFXPanel.addNotify(JFXPanel.java:883)
	at java.desktop/java.awt.Container.addNotify(Container.java:2797)
	at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4783)
	at java.desktop/java.awt.Container.addNotify(Container.java:2797)
	at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4783)
	at java.desktop/java.awt.Container.addNotify(Container.java:2797)
	at java.desktop/javax.swing.JComponent.addNotify(JComponent.java:4783)
	at java.desktop/javax.swing.JRootPane.addNotify(JRootPane.java:733)
	at java.desktop/java.awt.Container.addNotify(Container.java:2797)
	at java.desktop/java.awt.Window.addNotify(Window.java:786)
	at java.desktop/java.awt.Frame.addNotify(Frame.java:490)
	at java.desktop/java.awt.Window.pack(Window.java:824)
	at test.sandbox.app.JFXPanelApp.initApp(JFXPanelApp.java:78)
	at test.sandbox.app.JFXPanelApp.<init>(JFXPanelApp.java:136)
	at test.sandbox.app.JFXPanelApp.lambda$runTest$3(JFXPanelApp.java:154)
	at java.desktop/java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:313)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:770)
	at java.desktop/java.awt.EventQueue.access$600(EventQueue.java:97)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:721)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:715)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:87)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:740)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)


test.sandbox.SandboxAppTest > testJFXPanelImplicitExitApp FAILED
    junit.framework.AssertionFailedError: test.sandbox.app.JFXPanelImplicitExitApp: Application failed with a security exception
        at test.sandbox.SandboxAppTest.runSandboxedApp(SandboxAppTest.java:85)
        at test.sandbox.SandboxAppTest.testJFXPanelImplicitExitApp(SandboxAppTest.java:119)

The launched application for this test gets the same exception.


Comments
The security manager will be deprecated for removal in JDK 17 as part of JEP 411, JDK-8264713. Given this, along with my previous comments about the impact and workaround, we don't plan to fix this bug.
15-04-2021

The reason for the failures are two-fold: 1. The javafx.swing and jdk.unsupported.desktop modules are loaded by the AppClassLoader. This means that they do not get special permission to access classes in internal packages bypassing the package access security check. This came up during the review of the jdk.unsupported.desktop API along with the initial FX swing interop prototype. 2. The jdk.unsupported.desktop package has no privileges (actually, neither does the javafx.swing module, but we provide a policy file for testing that grants all permissions). This means that classes from jdk.unsupported.desktop cannot call into internal packages of java.desktop at all when there is a security manager enabled. And if permissions were granted in the default.policy file in the JDK, we would then need to change the jdk.unsupported.desktop code to load all internal classes within a doPrivileged. This would require a fair bit of work, and analysis to make sure we got all the needed places without opening up any security holes. Since OpenJFX is an external library, and no longer a privileged part of the JDK, JavaFX applications that want to use a security manager will need to do it at the application level anyway -- meaning they will need to provide a policy file granting privileges to the javafx modules. It is not nearly as important to be able to run with a security manager using a user-provided policy file that grants permissions to javafx modules without granting those same permissions to the application. Conclusion: We should not even try to address this in the JDK 11 time frame. Given that running desktop applications with a security manger is not all that common a thing to do, and that the application can work around this by granting the necessary permissions to their application at the same time they provide it to the javafx modules, we should defer this to JDK 12 (and may end up not fixing it without a compelling use case). I will retarget this bug to openjfx12 and file a new bug for openjfx11 to disable the two failing tests.
20-07-2018

Added doPrivileged calls to few methods. http://cr.openjdk.java.net/~psadhukhan/fx/8202451/webrev.0/
17-07-2018

Raising priority to P3, since this is a regression in functionality. I note that the fixes for JDK-8195811 and JDK-8202199 are necessary, but may not be sufficient to solve this bug.
04-05-2018

This was discovered while testing the fix for JDK-8198329 using the standalone FX SDK. This is a direct result of accessing internal packages in java.desktop, which are restricted when running with a security manager. When FX is part of the JDK, it can load and access these classes even when a security manager is enabled. When the javafx modules are loaded by the AppClassLoader, which it will be with the standalone FX, a security check is performed, which will fail when running sandboxed applications. As mentioned in the evaluation of JDK-8198329, this is likely not something we will fix. Once we implement JDK-8195811 using the new public (unsupported) Swing interop API this will no longer be a problem, and it isn't worth fixing in the interim. I recommend testing this as part of implementing JDK-8195811 and closing it as a duplicate once it is proven that that fixes the problem.
30-04-2018