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 [1] project, an open source SQL access library
>>> atop JDBC.
>>>
>>> A major part of our API provides implementations of declarative
>>> interfaces
>>> defined by users (similar to MyBatis). Interface methods may be
>>> default (in
>>> which case the default method implementation is used) or abstract (in
>>> which
>>> case JDBI provides the implementation).
>>>
>>> We're using JDK 8, and we use java.lang.reflect.Proxy and
>>> InvocationHandler
>>> to provide declarative interface implementations for our users.
>>>
>>> Prior to release of JDK 8, it appears that the subject of enhancing
>>> Proxies
>>> for default methods was discussed [2], but ultimately did not make it
>>> into
>>> 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 [3].
>>>
>>> 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 [4], but it's hard to
>>> tell
>>> 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:
>>
>> http://mail.openjdk.java.net/pipermail/core-libs-dev/2016-June/041629.html
>>
>>
>> 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.
>
> Mandy
>
>

-- 
- DML


More information about the jpms-spec-experts mailing list