RFR: 8159746: (proxy) Support for default methods

Peter Levart plevart at openjdk.java.net
Wed Oct 28 08:44:25 UTC 2020


On Wed, 28 Oct 2020 08:35:47 GMT, Peter Levart <plevart at openjdk.org> wrote:

>> Hi Peter,
>> 
>>> Question remains how do we distinguish proxies with old-fassioned InvocationHandlers from proxies with InvocationHandlers having access to super-default-handler. Both kinds of handlers look the same from Proxy's perspective... Perhaps we need a boolean flag in Proxy instance for that, coupled with an overloaded constructor that takes it...
>> 
>> I have the Proxy constructor taking both the invocation handler and `superHandler` in my [mlchung:proxy-default-method-4](https://github.com/mlchung/jdk/tree/proxy-default-method-4) branch.
>> 
>>> Problem with this approach is that it is not really useful in the proxy instance. We don't need it in the proxy instance. 
>> 
>> See above.
>> 
>> About the exception thrown: we need to distinguish CCE and NPE thrown by the default method vs thrown by arguments incompatible with the method signature.  In my proxy-default-method-4 branch, I define an internal exception type for that.  There is an overhead doing the wrapping but it's an exception case which performance should not be critical.
>
>> Hi Peter,
>> 
>> > Question remains how do we distinguish proxies with old-fassioned InvocationHandlers from proxies with InvocationHandlers having access to super-default-handler. Both kinds of handlers look the same from Proxy's perspective... Perhaps we need a boolean flag in Proxy instance for that, coupled with an overloaded constructor that takes it...
>> 
>> I have the Proxy constructor taking both the invocation handler and `superHandler` in my [mlchung:proxy-default-method-4](https://github.com/mlchung/jdk/tree/proxy-default-method-4) branch.
>> 
> 
> Yes, but it is not really useful there. The super handler is captured by the user invocation handler created in the invocation handler factory function and it is only used by the user invocation handler. All we need in the proxy instance is a boolean flag indicating the way the invocation handler was created (which one of the two overloaded newProxyInstance methods was called).
> 
>> > Problem with this approach is that it is not really useful in the proxy instance. We don't need it in the proxy instance.
>> 
>> See above.
>> 
>> About the exception thrown: we need to distinguish CCE and NPE thrown by the default method vs thrown by arguments incompatible with the method signature. In my proxy-default-method-4 branch, I define an internal exception type for that. There is an overhead doing the wrapping but it's an exception case which performance should not be critical.
> 
> To be precise, we need to pass CCE and NPE thrown by the default method unchanged, but we need to wrap CCE and NPE thrown by the method handle transformation chain with IllegalArgumentException. Is that what you are referring to? In that case we need an internal exception type, not exposed to public API, used just to "tunnel" the exception from the default method unchanged. That's just implementation detail.
> 
> But we have to ask ourselves a question: "Do we want to wrap CCE and NPE thrown by the method handle transformation chain with IllegalArgumentException?". We did that in previous variants to mimic the Method.invoke specification. But now we already departed from that specification by not wrapping exceptions thrown by the default method with InvocationTargetException. So we are not obligated to follow the rest of the Method.invoke specification either. All exception types thrown by method handle transformation chain (CCE, NPE, IAE) are unchecked exceptions and as such are not eligible to wrapping with UndeclaredThrowableException by the Proxy API. So it's just a matter of deciding what is more suitable: to have more specific exception types (CCE, NPE, IAE) for describing transformation exceptions or to reduce them to one common type (IAE). In either case those exception types can also be thrown by the default method and we can't or even want to distinguish their source. Let's be hon
 est, all of CCE, NPE, IAE are usually describing the subtle variants of the same thing: that the parameters are wrong. Whether this happens in the logic of invocation handler, method handle transformation chain or the default method, we want those exceptions to propagate out of the invoked proxy method unchanged.
> 
> So WDYT?

> Hi Peter,
> 
> About the exception thrown: ...

What I was referring to in my message before the last was about reflective access exeption thrown by Proxy.getInvocationHandler() when the handler has access to super invocation handler and the caller does not have access to proxy interfaces. What to do about that. Is UncheckedReflectiveOperationException a suitable solution? I'm not particularly fond of creating another Proxy.invocationHandler method, because it does not solve the problem of the old method that may also be called.

-------------

PR: https://git.openjdk.java.net/jdk/pull/313


More information about the core-libs-dev mailing list