proxy an interface and call a default method
Peter Levart
peter.levart at gmail.com
Fri Jun 3 09:51:29 UTC 2016
On 06/02/2016 06:34 PM, forax at univ-mlv.fr wrote:
>
> So perhaps, instead of providing a Proxy::findSuper method that
> returns a pre-bound MH, there could simply be a method like the
> following in the Proxy class:
>
> public final Object invokeSuper(Class<?> interfaze, String
> methodName, MethodType methodType, Object ... args) { ... }
>
> What do you think?
>
>
> yes, good idea,
> i think it should be static (and takes a Proxy as parameter) to avoid
> unwanted overriding.
Something like the following?
http://cr.openjdk.java.net/~plevart/jdk9-dev/Proxy.invokeSuperDefaults/webrev.02/
Usage is even simpler with this API:
public class Test {
interface I1 {
default void m() {
System.out.println("default I1.m() called");
}
}
interface I2 {
default void m() {
System.out.println("default I2.m() called");
}
}
interface I12 extends I1, I2 {
@Override
void m();
}
public static void main(String[] args) {
InvocationHandler h = (proxy, method, params) -> {
System.out.println("InvocationHandler called for: " + method);
try {
return Proxy.invokeSuper(proxy, method, params);
} catch (InvocationTargetException e) {
throw e.getCause();
}
};
I1 i1 = (I1) Proxy.newProxyInstance(
I1.class.getClassLoader(), new Class<?>[]{I1.class}, h);
i1.m();
I2 i2 = (I2) Proxy.newProxyInstance(
I2.class.getClassLoader(), new Class<?>[]{I2.class}, h);
i2.m();
I12 i12 = (I12) Proxy.newProxyInstance(
I12.class.getClassLoader(), new Class<?>[]{I12.class}, h);
i12.m();
}
}
Gives the following output:
InvocationHandler called for: public default void Test$I1.m()
default I1.m() called
InvocationHandler called for: public default void Test$I2.m()
default I2.m() called
InvocationHandler called for: public abstract void Test$I12.m()
Exception in thread "main" java.lang.reflect.UndeclaredThrowableException
at $Proxy2.m(Unknown Source)
at Test.main(Test.java:49)
Caused by: java.lang.IllegalAccessException: no such method:
Test$I12.m()void/invokeSpecial
at
java.lang.invoke.MemberName.makeAccessException(java.base at 9-internal/MemberName.java:928)
at
java.lang.invoke.MemberName$Factory.resolveOrFail(java.base at 9-internal/MemberName.java:1064)
at
java.lang.invoke.MethodHandles$Lookup.resolveOrFail(java.base at 9-internal/MethodHandles.java:1692)
at
java.lang.invoke.MethodHandles$Lookup.findSpecial(java.base at 9-internal/MethodHandles.java:1150)
at
java.lang.reflect.Proxy.invokeSuper(java.base at 9-internal/Proxy.java:1151)
at Test.lambda$main$0(Test.java:33)
... 2 more
Caused by: java.lang.AbstractMethodError: Test$I12.m()V
at
java.lang.invoke.MethodHandleNatives.resolve(java.base at 9-internal/Native
Method)
at
java.lang.invoke.MemberName$Factory.resolve(java.base at 9-internal/MemberName.java:1036)
at
java.lang.invoke.MemberName$Factory.resolveOrFail(java.base at 9-internal/MemberName.java:1061)
... 6 more
...which is expected. You can't call the super abstract method. You have
to resolve the Method object of a particular interface (I1 or I2)
yourself in such case.
I think this is a simple API that everyone could understand.
Regards, Peter
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20160603/96e3f26f/attachment.html>
More information about the mlvm-dev
mailing list