JDK-8195801 : Replace jdk.internal.misc.Unsafe with sun.misc.Unsafe in MarlinFX
  • Type: Bug
  • Component: javafx
  • Sub-Component: graphics
  • Affected Version: 9,10,openjfx11
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2018-01-19
  • Updated: 2018-06-13
  • Resolved: 2018-01-26
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.
Other
openjfx11Fixed
Related Reports
Blocks :  
Relates :  
Description
The Marlin rasterizer uses jdk.internal.misc.Unsafe to allocate off-heap arrays.

In an effort to eliminate the use of internal packages from core module by javafx.* modules we need an alternative solution.
Comments
Changeset: 305d127c6ed5 Author: kcr Date: 2018-01-26 08:04 -0800 URL: http://hg.openjdk.java.net/openjfx/jfx-dev/rt/rev/305d127c6ed5 8195801: Replace jdk.internal.misc.Unsafe with sun.misc.Unsafe in MarlinFX Reviewed-by: mchung, lbourges
26-01-2018

+1
26-01-2018

Perfect, Kevin. Thanks
26-01-2018

http://cr.openjdk.java.net/~kcr/8195801/webrev.02/ Updated with your recommendations from above. Again, the only change is to OffHeapArray.java
26-01-2018

Kevin, I looked at the webrev.1 and it looks very close to the code I have for years in Marlin @ github (compatible with 1.6 to 1.8). As said before, I would prefer having a consistent code across Marlin, 2d & FX so convergence is important (compatible with 1.6 to 11 ?) Here is the code (not using lambda) I have now: UNSAFE = AccessController.doPrivileged(new PrivilegedAction<Unsafe>() { @Override public Unsafe run() { Unsafe ref = null; try { final Field field = Unsafe.class.getDeclaredField("theUnsafe"); field.setAccessible(true); ref = (Unsafe) field.get(null); } catch (Exception e) { MarlinUtils.logInfo("Unable to get sun.misc.Unsafe; exit now."); System.exit(1); } return ref; } }); However I like your exception handling so I would change my code to: } catch (Exception e) { throw new InternalError("Unable to get sun.misc.Unsafe instance", e); }
26-01-2018

sun.misc.Unsafe.getUnsafe() is a public static method that does the security permission check. You use reflection to bypass the check which is okay for this dance. JDK 9 Unsafe.getUnsafe() restricts it to be called by classes loaded by the bootstrap loader but relax to allow called by classes defined by the platform class loader as well in JDK 10 (JDK-8161121). That's why you got SecurityException when running with JDK 9 but works on JDK 10.
25-01-2018

Updated webrev: http://cr.openjdk.java.net/~kcr/8195801/webrev.01/ The only change is to the static initializer block in OffHeapArray.java I did all my initial testing with JDK 10. While doing follow-on testing, I discovered that it doesn't run with JDK 9, due to a SecurityException. The "recommended" pattern to get at the instance of Unsafe is to use reflection as follows, rather than calling the Unsafe::getUnsafe method: Field f_theUnsafe = Unsafe.class.getDeclaredField("theUnsafe"); f_theUnsafe.setAccessible(true); Unsafe theUnsafe = (Unsafe) f_theUnsafe.get(null); I don't yet want to bump the minimum boot JDK to 10, so I will make this change to use reflection to get the instance. More importantly, I don't know why this works in JDK 10, since the code that throws the security exception is still present. I'm concerned that opening it up may have been unintentional, and so it might be "closed off" again.
25-01-2018

Marlin code changes look good to me.
25-01-2018

Looks good to me.
25-01-2018

Webrev: http://cr.openjdk.java.net/~kcr/8195801/webrev.00/ Simple fix as outlined above.
25-01-2018

Steps to fix this: 1. Add "requires jdk.unsupported" to the module-info.java of the javafx.graphics module; this also requires adding the necessary "--add-reads" statement to buildSrc/addExports: # Add reads for JDK-8195801 --add-reads=javafx.graphics=jdk.unsupported 2. Replace all imports of jdk.unsupported.misc.Unsafe with sun.misc.Unsafe 3. Remove the call to Unsafe::allocateUninitializedArray which does not exist in the legacy sun.misc.Unsafe class
23-01-2018

The simplest fix for JDK 11 is to switch back to using sun.misc.Unsafe, which is publicly exported via in the jdk.unsupported module.
22-01-2018

Note that the qualified export of jdk.internal.misc to javafx.graphics can only be removed once both of JDK-8195802 and JDK-8195801 (this bug) are resolved. Which ever one is done last can / should remove the qualified export.
19-01-2018