inner classes mixed with method handles: does it matter?

Rémi Forax forax at univ-mlv.fr
Fri Oct 22 09:15:43 PDT 2010


Le 22/10/2010 12:34, John Rose a écrit :
> The JSR 292 EG is discussing access rules for method handles.
>
> The draft spec. say that CONSTANT_MethodHandles in the constant pool, and dynamically looked up method handles, are accessible to related nested classes:
>
>       * In general, the conditions under which a method handle may be
>       * created for a method {@code M} are exactly as restrictive as the conditions
>       * under which the lookup class could have compiled a call to {@code M}.
>       * This rule is applied even if the Java compiler might have created
>       * an wrapper method to access a private method of another class
>       * in the same top-level declaration.
>       * For example, a lookup object created for a nested class {@code C.D}
>       * can access private members within other related classes such as
>       * {@code C}, {@code C.D.E}, or {@code C.B}.
>
> That is, method handle constants, and method handles obtained from dynamic member lookup, can access private members of other classes, if and only if those other classes are nest-mates of the requesting class.
>
> It is as if the corresponding Core Reflection API object has its "accessible" bit set to true, if the requesting class and the target member's class are both under the same package member, as determined by repeated use of Class.getEnclosingClass, and subject to the JVM's consistency checks on that query.
>
> Question for users:  If we were to drop this feature, and use the more limited access rules from reflection, would anybody miss it?  If you are generating code, you'll have to generate "access$" methods like javac, or just not use privates.  If you are reflecting, you'll have to do the setAccessible(true) dance.
>
> In any case, you always have Lookup.unreflect(Method), and you can setAccessible on the Method to disable access checking.  The problem with setAccessible is that it requires privilege elevation.
>
> Even if your language does not emit inner classes (very few do) this issue may affect it, if you are relying on access to non-public members of Java classes.  In this case, getting a method handle on a nested class member may be done with a Lookup object on its enclosing class (or any other nest-mate) in the draft design, but must be done with a Lookup object on the exact inner class, if we drop this feature.
>
> Comments?
>    

Inner class is a Java artifact, not a VM one.
So Lookup should work using the VM rules not the Java rules:
a nested class C.D can't access to private members of C because
C$D is a class and C another one.

If we relax that rule, some calls will work with method handles but
not with the equivalent bytecode.
So runtimes will have to generate an invokedynamic instead of
an invokevirtual to bypass the VM security rule.

In my opinion, if your language support inner classe, it's simpler
to generate accessors like javac does and to keep the same
accessible rules.

> -- John
>    

Rémi


More information about the mlvm-dev mailing list