RFR: 8159746: (proxy) Support for default methods
Peter Levart
plevart at openjdk.java.net
Wed Oct 28 08:38:22 UTC 2020
On Wed, 28 Oct 2020 03:06:04 GMT, Mandy Chung <mchung 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.
>
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 hones
t, 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?
-------------
PR: https://git.openjdk.java.net/jdk/pull/313
More information about the core-libs-dev
mailing list