question on exports to

Peter Levart peter.levart at gmail.com
Wed Jun 1 18:54:35 UTC 2016



On 06/01/2016 08:05 PM, 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...

Modules are part of language. Their exports / requires form a logical 
layer of additional access checks to what we had before 
(public/protected/package/private qualifiers on classes / members), but 
are treated the same way during runtime. Together they form language 
accessibility rules. There are exceptions, notably in reflection:
- Member.setAccessible(true) can not be used to circumvent lack of exports
- readability is implicitly provided for reflective access in general

So the trick with Lookup shown above can be used to invoke a private or 
package-private method via TheInvoker.invoke() like it was invoked directly:

class MyOtherClass {
      private void myPrivateMethod() {
         ...
     }

     void someMethod() {
         TheInvoker.invoke(MethodHandles.lookup(), this, "myPrivateMethod");
     }
}

...as well as other public methods in modules that export packages to 
the Lookup owner (the module of the class that obtains the Lookup object 
via MethodHandles.lookup()).

>
>
> bye Jochen


Regards, Peter


More information about the jigsaw-dev mailing list