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