Hi Jochen,
On 07/11/2016 12:24 PM, Jochen Theodorou wrote:
On 11.07.2016 11:43, Peter Levart wrote:
[...]
Here's a simplified idea. Suppose MyReflection uses java reflection to
invoke target methods directly and it is already arranged so that
MyReflection has access to hidden methods in both M1 and M2 (let's take
the generated M1|M2Accessor(s) out of the picture for now - the idea can
be extended to include them later). Suppose that simplified MyReflection
is used to invoke just static methods in the module of the original
caller:
public class MyReflection {
public interface AccessToken {}
public static Object invoke(AccessToken accessToken,
Class<?> target, String methodName,
Class<?>[] parameterTypes, Object
... args)
throws IllegalAccessException,
NoSuchMethodException,
InvocationTargetException
{
if (accessToken.getClass().getModule() != target.getModule()) {
throw new IllegalAccessException("Cross module call");
}
return target.getDeclaredMethod(methodName, parameterTypes)
// this is a reflective call, but it could as well
be a call made by generated accessor
.invoke(null, args);
}
}
The original invoker and the hidden target method in M1 could then look
like:
public class CM1 {
public static int hiddenAdd(int a, int b) {
return a + b;
}
// keep the instance of AccessToken private and only pass it to
MyReflection
private static final MyReflection.AccessToken ACCESS =
new MyReflection.AccessToken() {};
public static void main(String[] args) throws Exception {
int sum = (Integer)
MyReflection.invoke(ACCESS,
CM1.class, "hiddenAdd", new
Class<?>[]{int.class, int.class},
10, 20);
}
}
As long as instance(s) of AccessToken implemented by classes in M1 are
kept private and only passed to MyReflection, MyReflection can verify
that the one that has access to such instance is an authorized caller so
it grants it access to hidden methods in M1.
For me you are confirming, that with MethodHandles, it will become the
responsibility to check module access rights and that calls from
hidden M1 to hidden M2 become possible.
bye Jochen
I think you misunderstood me. With MethodHandle(s) and Lookup(s) it is
the responsibility of the Lookup object to check the access rights while
Lookup object also acts a an access token as it caries the identity of
the "obtainer" - the one that called Methodhandles.lookup() to obtain
the instance.
The alternative that I presented 2nd is something that doesn't involve
MethodHandle(s) or Lookup(s). In this alternative, when a central party
(MyReflection) dispatches calls of multiple caller(s), each from its own
module, it has to have privileged access to the target methods in all
the modules where target methods live. The original caller must then
"authenticate" somehow to the central party in order for central party
to authorize the call. I presented a simple solution with a
SecurityToken marker interface.
So if you take the MethodHandle/Lookup route, the checking is already
there and follows JVM rules for bytecode invocations. If you take the
route of exposing hidden classes to MyReflection, then you will have to
provide the authentication and authorization yourself.
Regards, Peter