Proposal: Allow illegal reflective access by default in JDK 9

Peter Levart peter.levart at gmail.com
Fri May 19 10:58:39 UTC 2017


Hi Nikolai,

On 05/19/2017 12:41 PM, Nicolai Parlog wrote:
>   Hi!
>
> I'm too lazy to try right now

It's easy. Take this example:

public class Test {
     public static void main(String[] args) throws Exception {
         Object theUnsafe = Class.forName("jdk.internal.misc.Unsafe")
                                 .getMethod("getUnsafe")
                                 .invoke(null);
     }
}

Running this on classpath without any additional JVM options produces:

Exception in thread "main" java.lang.IllegalAccessException: class Test 
cannot access class jdk.internal.misc.Unsafe (in module java.base) 
because module java.base does not export jdk.internal.misc to unnamed 
module @63d4e2ba
     at 
java.base/jdk.internal.reflect.Reflection.throwIllegalAccessException(Reflection.java:445)
     at 
java.base/jdk.internal.reflect.Reflection.throwIllegalAccessException(Reflection.java:436)
     at 
java.base/jdk.internal.reflect.Reflection.ensureMemberAccess(Reflection.java:112)
     at 
java.base/java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:407)
     at 
java.base/java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:399)
     at java.base/java.lang.reflect.Method.invoke(Method.java:535)
     at Test.main(Test.java:9)

(note that the exception is thrown from Method.invoke)

When run with:

      --add-exports java.base/jdk.internal.misc=ALL-UNNAMED

...the example works (does not throw exception), but when run with:

     --add-opens java.base/jdk.internal.misc=ALL-UNNAMED

...the example still works!!!! OOOPS - this is a bug!!! This is 
definitely a bug.


If --illegal-access=permit is an alias for opening all modules to 
ALL-UNNAMED, then we definitely have a problem as above example can be 
successfully executed even with SecurityManager enabled!!!


Regards, Peter

>   but I'm pretty sure I repeatedly observed
> the behavior Volker describes:
>
> A module depends on an internal type and is compiled successfully
> thanks to --add-exports. At run time it would fail without flags and
> would work with --add-exports but it also works with --add-opens.
>
>   so long ... Nicolai
>
>
>
> On 19.05.2017 12:24, Peter Levart wrote:
>> Hi Volker,
>>
>> On 05/19/2017 11:48 AM, Volker Simonis wrote:
>>>  From my understanding, at run-time, "open" implicates "exports"
>>> (i.e. if a module M1 opens a package P for some other module M2
>>> it also, implicitly exports P to M2). The  "big kill switch" in
>>> both, its old and in the newly proposed form, usually only refers
>>> to "enabling reflective access" but doesn't explicitly mentions
>>> that it will also, implicitly export the respective packages.
>>> Also, the usage of the "kill switch" only produces warnings for
>>> reflective accesses which are enabled by the option itself (and
>>> not at the same time, explicitly allowed by --add-opens
>>> directives). But it doesn't warn about the simple, non-reflective
>>> accesses to packages which are implicitly exported by the kill
>>> switch as well.
>> No, you got it wrong. "opens" is just a backdoor for reflection
>> (and MethodHandles.Lookup). It does not implicitly also mean
>> "exports". Neither in compile-time nor in run-time. Otherwise
>> everything that is declared "public" would be accessible to
>> reflection without the need for .setAccessible(true) - therefore
>> even to code running with SecurityManager enabled!
>>
>> Regards, Peter
>>



More information about the jigsaw-dev mailing list