When jdk9 is released, an army of white, black, grey, and red hats will try to keep their old Unsafe hacks alive and maybe get their hands on a jdk.internal.misc.Unsafe. Here's some code that tries to do that. The call to setAccessible succeeds! And the code succeeds in getting hold of jdk.internal.misc.Unsafe.class and of its instance before finally failing with IllegalAccessError. So this may actually be safe, in that user code may not be able to actually invoke methods on their ill-gotten Unsafe object, but the intent is probably that they shouldn't be able to get this far:
/** * javac -Xmodule:java.base GetUnsafe9.java && java GetUnsafe9 */ public class GetUnsafe9 { public static void main(String[] args) throws Throwable { Class<?> klazz = java.util.concurrent.ConcurrentHashMap.class; for (java.lang.reflect.Field field : klazz.getDeclaredFields()) { if (field.getName().equals("U")) { field.setAccessible(true); System.out.println(field); Object theUnsafe = field.get(null); System.out.println(theUnsafe); Class<jdk.internal.misc.Unsafe> unsafeClass = (Class<jdk.internal.misc.Unsafe>) theUnsafe.getClass(); System.out.println(unsafeClass); jdk.internal.misc.Unsafe U = unsafeClass.cast(theUnsafe); } } } } private static final jdk.internal.misc.Unsafe java.util.concurrent.ConcurrentHashMap.U jdk.internal.misc.Unsafe@35851384 class jdk.internal.misc.Unsafe Exception in thread "main" java.lang.IllegalAccessError: class GetUnsafe9 (in unnamed module @0x649d209a) cannot access class jdk.internal.misc.Unsafe (in module java.base) because module java.base does not export jdk.internal.misc to unnamed module @0x649d209a at GetUnsafe9.main(GetUnsafe9.java:16) On Thu, Jul 7, 2016 at 7:54 AM, Andrew Dinn <ad...@redhat.com> wrote: > On 07/07/16 14:59, Volker Simonis wrote: > > - I was a little bit surprised that I could reflectively access and > > execute java.lang.VersionProps.parseVersionNumbers() where both the > > class and the method are package private. Maybe this is related to > > Jigsaw issue #ReflectiveAccessToNonExportedTypes [3]? As I'm not a > > Jigsaw expert, I'd be graceful to anybody explaining me why this is > > still so easily possible with Jigsaw? > > Reflective access to non-public classes/members of exported packages is > unchanged with Jigsaw -- it is subject to the security checks in place > in previous JDKs but not to a module access check. So, in this case > java.lang is an exported package which means you can obtain a handle on > java.lang.VersionProps.parseVersionNumbers(), call setEnabled(true) and > then invoke it. > > It is only when you try to reflectively access non-public > classes/members of packages that are not exported by their owning module > that the check comes into play. So, if your (non-module) code obtains a > reflective Member for jdk.internal.misc.Unsafe.theUnsafe and calls > setEnabled(true) you will find that the latter call will not succeed in > rendering it an accessible handle and an access via that handle will > fail. That is because java.base does not export package > jdk.internal.misc so the module check under setEnabled detects that the > caller is in a different module and refuses to make it accessible. > > regards, > > > Andrew Dinn > ----------- > Senior Principal Software Engineer > Red Hat UK Ltd > Registered in England and Wales under Company Registration No. 03798903 > Directors: Michael Cunningham, Michael ("Mike") O'Neill, Eric Shander >