invoking a interface default method from within an InvocationHandler

Remi Forax forax at univ-mlv.fr
Thu Oct 9 17:07:25 UTC 2014


public static void main(String[] args) throws NoSuchFieldException, 
IllegalArgumentException, IllegalAccessException {
     Lookup lookup = MethodHandles.publicLookup().in(Consumer.class);
     Field allowedModes = Lookup.class.getDeclaredField("allowedModes");
     allowedModes.setAccessible(true);
     allowedModes.set(lookup, Modifier.PRIVATE);

     @SuppressWarnings("unchecked")
     Consumer<Object> consumer = (Consumer<Object>)Proxy.newProxyInstance(
         CallingADefaultMethodInAProxy.class.getClassLoader(),
         new Class<?>[]{Consumer.class},
         (Object proxy, Method method, Object[] array) -> {
             if (method.isDefault()) {
               MethodHandle mh = lookup.unreflectSpecial(method, 
Consumer.class);
               return 
mh.invokeWithArguments(Stream.concat(Stream.of(proxy), 
Arrays.stream(array)).toArray());
             }
             System.out.println("hello");
             return null;
         });

     consumer.andThen(System.out::println).accept("default method");
   }

Not very pretty, if someone ask me I will deny to have written that code :)

John, I've discovered that findSpecial/unreflectSpecial doesn't honor 
setAccessible,
given that the whole point of unreflectSpecial is to see a virtual call 
as a super call,
it looks like a bug to me.

Rémi

On 10/09/2014 04:42 PM, Jochen Theodorou wrote:
>
> too bad no-one knows. Has anyone an idea for a better place to ask 
> this? (btw, because of the getSimpleName issue I can't use 
> MethodHandleProxies)
>
> Am 06.10.2014 18:06, schrieb Jochen Theodorou:
>> Hi,
>>
>> I find this a little odd and I wonder how you are supposed to do it
>> right. Or if that is a bug.
>>
>> So I have a class implementing InvocationHandler and I used Proxy to
>> create a an proxied instance of Consumer. This is a functional interface
>> and I want to use its accept method for my purposes, while still keeping
>> the old andThen method as it is.
>>
>> going by the usual signature for the InvocationHandler implementation
>> main method (public Object invoke(Object proxy, Method method, Object[]
>> args) throws Throwable)
>>
>> I can do neither method.invoke on this, since that leads to that method
>> (overflow then) again, nor can I take the proxy object, since it
>> obviously has nothing to do with functional interface.
>>
>> Now... is that really on purpose? Are you indeed forced to split up your
>> code into a java7+ and pre java7 case to be able to use
>> MethodHandleProxies#asInterfaceInstance where it is available instead?
>> Shouldn't Proxy and InvocationHandler then be marked deprecated in
>> Java8? And how do you use MethodHandleProxies to implement multiple
>> interfaces?
>>
>> bye Jochen
>>
>
>



More information about the mlvm-dev mailing list