question on exports to

Alex Buckley alex.buckley at oracle.com
Wed Jun 1 19:07:02 UTC 2016


On 6/1/2016 11:05 AM, Jochen Theodorou wrote:
> On 01.06.2016 18:57, Peter Levart wrote:
> [...]
>>> Anyway... the groovy runtime would be almost something like java.base,
>>> but instead of being like a root element, this one will have to sit in
>>> the middle, because we depend on java as well.
>>>
>>>> If that is true, then perhaps there is a simpler solution that doesn't
>>>> require modifying the exports of any module.
>>>>
>>>> Make your TheInvoker take another argument of type
>>>> MethodHandles.Lookup:
>>>>
>>>> public class TheInvoker{
>>>>      public static Object invoke(MethodHandles.Lookup lookup, Object
>>>> receiver, String name, Object... args) throws Throwable {
>>>>          Method m = receiver.getClass().getDeclaredMethod(name,
>>>> toClass(args));
>>>>          MethodHandle mh = lookup.unreflect(m).bindTo(receiver);
>>>>          return mh.invokeWithArguments(args);
>>>>      }
>>>> ...
>>>> }
>>>>
>>>> Then pass the appropriate lookup to it from where you call
>>>> TheInvoker.invoke (from MyOtherLib):
>>>>
>>>> TheInvoker.invoke(MethodHandles.lookup(), receiver, "methodName",
>>>> arguments...);
>>>
>>> receiver.getClass().getDeclaredMethod would fail, if I cannot access
>>> the class of the receiver.
>>
>> No, for obtaining reflection objects you don't need language access
>> rights. You need security permissions if security manager is installed,
>> but that's independent of language access checks. Language access checks
>> are performed when you call Method::invoke or Field::get, etc... or when
>> you do Lookup::unreflect, but the later is performed against the "caller
>> class" that is captured inside the Lookup object.
>
> I was more thinking about modules here... well... now I am indeed
> confused. I thought I did see that module access rules are enforced, but
> I cannot find anything of that right now. So how does the module system
> enforce the module system at runtime? I mean if that is not the case,
> then why do I even need someething like Module#addReads? But the only
> part where I can see that happening right now is for setAccessible...

JDK 9 doesn't change class loading or class visibility in any way. You 
can still use x.class to get the Class for an object, and you can still 
call Class::getFields() and Class::getMethods() to get Field and Method 
objects. Core Reflection doesn't care about module readability. Pretend 
you never heard of Module::addReads, it's for a use case that doesn't 
matter here (generation of bytecode with constant pool references to 
classes in other modules).

Core Reflection is still bound by the Java language's notion of 
accessibility, so calling newInstance() on a Class or get() on a Field 
or invoke() on a Method will perform an access check in SE 9 just like 
in SE 8. The access check has two parts, as previously discussed, but by 
policy the first part (X-reads-Y) is a "yes" for these reflective 
operations ... that leaves second part where the underlying 
class/field/method must be exported to the code calling 
newInstance()/get()/invoke(). That's why setAccessible has been 
@CallerSensitive since the module system implementation was merged into 
JDK 9.

Alex


More information about the jigsaw-dev mailing list