javareflectionjava-7invokedynamicmethodhandle

Invoke private method with java.lang.invoke.MethodHandle


How can I invoke private method using method handles ?

As far as I can see there are only two kinds of publicly accessible Lookup instances:

and neither allows unrestricted private access.

There is the non-public Lookup.IMPL_LOOKUP that does what I want. Is there some public way to obtain it (assuming that SecurityManager allows it) ?


Solution

  • Turns out it's possible with Lookup#unreflect(Method) and temporarily making method accessible (potentially introducing small security issue unless done during program initialization).

    Here is modified main method from Thorben's answer:

    public static void main(String[] args) {
    
        Lookup lookup = MethodHandles.lookup();
        NestedTestClass ntc = new Program().new NestedTestClass();
    
        try {
            // Grab method using normal reflection and make it accessible
            Method pm = NestedTestClass.class.getDeclaredMethod("gimmeTheAnswer");
            pm.setAccessible(true);
    
            // Now convert reflected method into method handle
            MethodHandle pmh = lookup.unreflect(pm);
            System.out.println("reflection:" + pm.invoke(ntc));
    
            // We can now revoke access to original method
            pm.setAccessible(false);
    
            // And yet the method handle still works!
            System.out.println("handle:" + pmh.invoke(ntc));
    
            // While reflection is now denied again (throws exception)
            System.out.println("reflection:" + pm.invoke(ntc));
    
        } catch (Throwable e) {
            e.printStackTrace();
        }
    
    }