Fwd: Re: Invoking default methods from a Proxy's InvocationHandler in JDK9
David M. Lloyd
david.lloyd at redhat.com
Thu Mar 2 01:56:05 UTC 2017
According to the JDBI people, it seems that the security checks on
unreflectSpecial were relaxed for default methods. If this is the case
then I think we're OK here.
On 03/01/2017 04:37 PM, David M. Lloyd wrote:
> This keeps coming up. I think we'd better raise it as an issue because
> the workaround used in Java 8 is specifically broken by JPMS. In that
> regard, Peter Levart's workaround might be considered to fall under the
> FC extension umbrella.
> -------- Forwarded Message --------
> Subject: Re: Invoking default methods from a Proxy's InvocationHandler
> in JDK9
> Date: Tue, 3 Jan 2017 11:14:31 -0800
> From: Mandy Chung <mandy.chung at oracle.com>
> To: Peter Levart <peter.levart at gmail.com>
> CC: jigsaw-dev at openjdk.java.net
>> On Jan 2, 2017, at 11:20 PM, Peter Levart <peter.levart at gmail.com> wrote:
>> Hi Matthew,
>> On 01/03/2017 04:28 AM, Matthew Hall wrote:
>>> I'm a member of the JDBI  project, an open source SQL access library
>>> atop JDBC.
>>> A major part of our API provides implementations of declarative
>>> defined by users (similar to MyBatis). Interface methods may be
>>> default (in
>>> which case the default method implementation is used) or abstract (in
>>> case JDBI provides the implementation).
>>> We're using JDK 8, and we use java.lang.reflect.Proxy and
>>> to provide declarative interface implementations for our users.
>>> Prior to release of JDK 8, it appears that the subject of enhancing
>>> for default methods was discussed , but ultimately did not make it
>>> the release.
>>> The root of the problem is that the generated Proxy class overrides all
>>> methods in the proxy interfaces. This means that the interface default
>>> methods are now superclass methods to the proxy class, which makes them
>>> un-invokable from outside code--including the InvocationHandler.
>>> As far as we can tell, the _only_ way to invoke a default method--on a
>>> proxy, from an InvocationHandler--is to resort to some horrible
>>> setAccessible shenanigans .
>>> Specifically, we have to:
>>> 1. Call Constructor.setAccessible(true) to make the private constructor
>>> MethodHandles.Lookup(Class<?> lookupClass, int allowedModes) accessible,
>>> 2. Invoke that private constructor to instantiate a MethodHandles.Lookup
>>> with private (!) access to all the things,
>>> 3. Call Lookup.unreflectSpecial to get the MethodHandle for the default
>>> method, and
>>> 4. Invoke the method through the MethodHandle.
>>> This is ugly, but it works--for now. If JDK 9 takes away access to
>>> setAccessible, it may cease to work.
>>> I found some discussion about this last summer , but it's hard to
>>> if anything came out of the discussion.
>>> Is there anything on the roadmap for JDK9 to allow a proxy's
>>> InvocationHandler to invoke default methods on proxies? Are there any
>>> existing proposals I should be aware of?
>> I have created a prototype last year:
>> But I think the JDK 9 train has already left the station. So perhaps
>> in JDK 10...
> https://bugs.openjdk.java.net/browse/JDK-8159746 is the JBS issue for this.
> One other possibility is to fix proxy generated class not to override
> default methods but there would require more investigation to tease out
> before we can be certain if this can make JDK 9.
More information about the jpms-spec-observers