method handle cracking API

Peter Levart peter.levart at gmail.com
Wed May 15 02:39:57 PDT 2013


Hi John,

I peeked at the implementation of HMI.asMember method:

       111 +    // Helper for default MethodHandleInfo.asMember.
       112 +    static Member reflectMember(MethodHandleInfo self) 
throws ReflectiveOperationException {
       113 +        int mods = self.getModifiers();
       114 +        if (mods == -1)  throw notDirectMethodHandle();
       115 +        byte refKind = (byte) self.getReferenceKind();
       116 +        Class<?> defc = self.getDeclaringClass();
       117 +        boolean isPublic = Modifier.isPublic(mods);
       118 +        if (MethodHandleNatives.refKindIsMethod(refKind)) {
       119 +            if (isPublic)
       120 +                return defc.getMethod(self.getName(), 
self.getMethodType().parameterArray());
       121 +            else
       122 +                return 
defc.getDeclaredMethod(self.getName(), 
self.getMethodType().parameterArray());
       123 +        } else if 
(MethodHandleNatives.refKindIsConstructor(refKind)) {
       124 +            if (isPublic)
       125 +                return 
defc.getConstructor(self.getMethodType().parameterArray());
       126 +            else
       127 +                return 
defc.getDeclaredConstructor(self.getMethodType().parameterArray());
       128 +        } else if 
(MethodHandleNatives.refKindIsField(refKind)) {
       129 +            if (isPublic)
       130 +                return defc.getField(self.getName());
       131 +            else
       132 +                return defc.getDeclaredField(self.getName());
       133 +        } else {
       134 +            throw new 
IllegalArgumentException("referenceKind="+refKind);
       135 +        }
       136 +    }
...
       408 +    public default <T extends Member> T asMember(Class<T> 
expected) {
       409 +        Member mem = AccessController.doPrivileged(new 
PrivilegedAction<Member>() {
       410 +                public Member run() {
       411 +                    try {
       412 +                        return 
InfoFromMemberName.reflectMember(MethodHandleInfo.this);
       413 +                    } catch (ReflectiveOperationException ex) {
       414 +                        throw newInternalError(ex);
       415 +                    }
       416 +                }
       417 +            });
       418 +        return expected.cast(mem);
       419      }


Are special cases for public members just because the reflection API 
requires different privileges for public vs. declared member access? But 
InfoFromMemberName.reflectMember() is package-private and is called from 
within a PrivilegedAction in MHI.asMember() which is a system class. If 
MHI objects are not considered "security sensitive tokens" like MH 
objects, then perhaps MHI.asMember should not wrap the call to 
InfoFromMemberName.reflectMember() in a PrivilegedAction...


Regards, Peter

On 05/15/2013 07:58 AM, John Rose wrote:
> Here is an update on the method handle cracking API.
>
> Though we will probably make some small adjustments, it appears to be converging.
>
> http://cr.openjdk.java.net/~jrose/8008688/specdiff.02/
> http://cr.openjdk.java.net/~jrose/8008688/javadoc.02/
>
> Key points:
>
> - interface MethodHandleInfo (MHI) presents a "cracked" symbolic reference for the member underlying a direct method handle (DMH)
> - cracking of method handles which are not DMHs is left for the future
> - you need the original Lookup object associated with DMH creation in order to crack it; this prevents side-channels
>
> - there are access methods for the four components (ref kind, class, name, type) of the CONSTANT_MethodHandle (or equivalent information) that was used to create the DMH
> - there is a bridge (asMember) from MHI to the Core Reflection API (can be built by user but very complex)
> - there is a fast path to the modifier bits of the underlying member (for checking public, varargs, etc.)
> - there are two static utility methods on MHI, toString and getReferenceKindString
>
> - there is also an unchecked version of the cracker (revealDirectAsAccessibleObject), which always makes a security manager call and bridges directly to the Core Reflection API
>
> - Modifier.isVarArgs and Modifier.VARARGS are made public, because there was no standard test, and variable arity is a key MethodHandle property
>
> The implementation patch is refreshed:
>
> http://hg.openjdk.java.net/mlvm/mlvm/jdk/file/tip/meth-info-8008688.patch
>
> Changes since last E-mail:
>
> - added revealDirectAsAccessibleObject
> - revealDirectAsAccessibleObject performs the same strong SM check as setAccessible
> - when either revealDirect function is called on a non-DMH, you get NoSuchMethodException
> - refined the types and documentation of exceptions and throws
> - removed static methods from MHI, except getReferenceKindString and toString
> - moved isVarArgs to java.lang.reflect.Modifier, where it belongs
>
> Possible loose ends:
>
> - minor name changes
> - MHI.toMember needs a more precise spec, and the default method is dodgy
> - could change ReflectiveOperationExceptions to IllegalArgumentExceptions, since the range of possible ROEs is quite limited
>
> — John
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev



More information about the mlvm-dev mailing list