invoking a interface default method from within an InvocationHandler
Paul Sandoz
paul.sandoz at oracle.com
Wed Oct 15 16:54:56 UTC 2014
Hi Remi,
I did some brief evaluation of this area.
MethodHandleProxies.asInterfaceInstance currently does not support proxying to default methods. An InternalError will be thrown if a default method is invoked. It should be possible to fix using a trusted internal IMPL_LOOKUP to look up MHs that invokespecial. I believe this should be safe under the context of proxying.
The InvocationHandler case is a little more tricky (as you show below). There could be a static method on MethodHandleProxies that returns an InvocationHandler that if proxying to default methods gives the option to continue with the default or not. The InvocationHandler, on invocation, must verify that it's arguments are valid before proxying to a default method i.e. p is an instance of a proxy class. Under such circumstances i believe that should be safe.
Paul.
On Oct 9, 2014, at 7:07 PM, Remi Forax <forax at univ-mlv.fr> wrote:
> 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
>>>
>>
>>
>
> _______________________________________________
> mlvm-dev mailing list
> mlvm-dev at openjdk.java.net
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 841 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20141015/1bf71508/signature.asc>
More information about the mlvm-dev
mailing list