Invoking default methods from a Proxy's InvocationHandler in JDK9

Matthew Hall qualidafial at gmail.com
Tue Jan 3 03:28:09 UTC 2017


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