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