Invoking default methods from a Proxy's InvocationHandler in JDK9
Remi Forax
forax at univ-mlv.fr
Tue Jan 3 07:17:20 UTC 2017
I do not think that the workaround to create a Lookup object by reflection works with 9 given that java.lang.invoke is not declared as an open package.
John Rose has proposed to add a method to get a private Lookup object through sun.misc.Unsafe but as far as i know, this proposal goes nowhere.
You can still access to the private constructor of Lookup using defineAnonymousClass.
As you may already know, i've developed the Proxy2 library [1], exactly for that
(and to be far more efficient than a java.lang.reflect.Proxy).
regards,
Rémi
[1] https://github.com/forax/proxy2
----- Mail original -----
> De: "Matthew Hall" <qualidafial at gmail.com>
> À: jigsaw-dev at openjdk.java.net
> Envoyé: Mardi 3 Janvier 2017 04:28:09
> Objet: Invoking default methods from a Proxy's InvocationHandler in JDK9
> 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?
>
> Regards,
>
> Matthew Hall
>
> [1] https://github.com/jdbi/jdbi/
> [2]
> http://mail.openjdk.java.net/pipermail/lambda-dev/2012-August/005675.html
> [3]
> https://github.com/jdbi/jdbi/blob/jdbi3/sqlobject/src/main/java/org/jdbi/v3/sqlobject/DefaultMethodHandler.java
> [4]
> http://jigsaw-dev.1059479.n5.nabble.com/creating-proxies-for-interfaces-with-default-methods-td5711955.html
More information about the jigsaw-dev
mailing list