invoking a interface default method from within an InvocationHandler
Peter Levart
peter.levart at gmail.com
Sat Oct 18 16:59:19 UTC 2014
On 10/17/2014 11:58 AM, Paul Sandoz wrote:
> On Oct 16, 2014, at 12:43 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>
>> On 10/15/2014 06:54 PM, Paul Sandoz wrote:
>>> 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.
>> Another solution is to do not rely on j.l.r.Proxy to implement asInterfaceInstance but to generate a proxy using ASM,
>> in that case, handling default methods is easy, just do nothing (i.e. do not override a default method).
>> It will also solve the fact that the proxies generated by asInterfaceInstance are currently super slow
>> because of the InvocationHandler API require boxing.
> That's a good point, it's more involved and it would be nice to reuse implementing classes keyed off the functional interface, since a field can be defined for the proxying MH. Hmm... i wonder if we can leverage InnerClassLambdaMetafactory.
>
>
>> The real solution in my opinion is to create yet another API,
> Yes, i am thinking just in the 9 time-frame, beyond that, as you indicate below, there is much more scope to improve this area (via invoke or a class dynamic).
>
> Paul.
Hi Paul, Remi,
The complete solution will require new API, but the
java.lang.reflect.Proxy API could be improved a bit too. With
introduction of default interface methods it is somehow broken now.
Default interface methods enable interface evolution, but break existing
Proxy InvocationHandler(s) which are not prepared to handle new methods.
So perhaps a small improvement to Proxz API could be to add new factory
method that takes an additional a boolean flag indicating whether
generated proxy should override default methods and forward their
invocation to InvocationHandler or not. An all-or-nothing approach. I
know that even that is not trivial. Generated proxy class can implement
multiple interfaces and there can be conflicts. In that case, the
easiest solution is to bail out and refuse to generate a proxy class
with such combination of interfaces.
A starting point could be to re-implement current functionality using
ASM and then start experimenting with different approaches. What do you
think?
Regards, Peter
>> lets call it proxy 2.0 that takes an interface and a bootstrap method
>> as parameter and generate a class that will call the BSM when calling a method of the proxy class the first time
>> (the BSM will be called with a 4th parameter which is a method handle corresponding to the called method
>> so one can use MHs.reflectAs to get the corresponding j.l.r.Method object if necessary).
>> For a default method, the 4th parameter will be a method handle created with findSuper, so a user can choose
>> to implement it or to delegate to this mh.
>> And asInterfaceInstance is just a foldArguments between the method handle taken as parameter and
>> an exactInvoker (or a genericInvoker if parameter types mismatch).
>>
>> Compared to a j.l.r.Proxy, the proxy 2.0 API also need a way to store fields (or at least values) inside the generated proxy class
>> and a way to query that fields inside the BSM. This can be done exactly like this is done by the lambda proxy,
>> instead of returning a proxy class, the proxy 2.0 API will return a method handle that acts as a factory for creating
>> proxy instances of the proxy class (if the factory takes no arguments, as for the lambda proxy, the same constant object can be returned).
>> To get a mh getter from inside the BSM, because the BSM already have the lookup object, all you need is a convention that says
>> that the field names are something like arg0, arg1, etc.
>>
>> The nice thing about this API is that it cleanly separate the information that can be process from proxied interface(s)
>> (by example, JavaEE annotations) and the ones, more dynamic, that are specific to a proxy instance.
>> It also removes one level of indirection compared to the InvocationHandler proxy.
>>
>>
>>
>> _______________________________________________
>> mlvm-dev mailing list
>> mlvm-dev at openjdk.java.net
>> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20141018/2dbabdbe/attachment-0001.html>
More information about the mlvm-dev
mailing list