Hi Jake,

On 06/05/2016 08:28 AM, Jake Wharton wrote:
On Fri, Jun 3, 2016 at 10:58 AM Peter Levart <peter.lev...@gmail.com <mailto:peter.lev...@gmail.com>> wrote:

    InvocationHandler gets invoked for default methods, but it
    has not provision to forward such calls to the default implementations
    in the interfaces.


This isn't quite true. You can use MethodHandles to invoke the default method if the interface is public:

    Object returnValue = MethodHandles.lookup()
.in(declaringClass)
.unreflectSpecial(method, declaringClass)
.bindTo(proxy)
.invokeWithArguments(args);

You are right. It appears that such Lookup has more powers than bytecode.


If the interface is not public, things get a bit more tricky since you need an instance which ignores the visibility. The only way to get at this is through creating your own trusted instance for the interface type:

Constructor<Lookup> constructor =
        Lookup.class.getDeclaredConstructor(Class.class, int.class);
constructor.setAccessible(true);
Object returnValue = constructor.newInstance(declaringClass, -1 /* trusted */)
.unreflectSpecial(method, declaringClass)
.bindTo(proxy)
.invokeWithArguments(args);

That said, I'm all for an API that makes this easier! Please make sure it handles non-public interface types as well.

Right, the changes I made to Proxy class generation, construct the Lookup object in the proxy class' <clinit>. Such Lookup has access to any superinterface method by virtue of the proxy class being able to implement such interface (if it is a package-private interface, the proxy class is generated in the same package; if it is an interface in a non-exported package, the proxy class is generated in a dynamic module and qualified export is added to the module holding the interface; etc...).

Regards, Peter

Reply via email to