On 06/02/2016 06:34 PM, fo...@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@9-internal/MemberName.java:928) at java.lang.invoke.MemberName$Factory.resolveOrFail(java.base@9-internal/MemberName.java:1064) at java.lang.invoke.MethodHandles$Lookup.resolveOrFail(java.base@9-internal/MethodHandles.java:1692) at java.lang.invoke.MethodHandles$Lookup.findSpecial(java.base@9-internal/MethodHandles.java:1150) at java.lang.reflect.Proxy.invokeSuper(java.base@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@9-internal/Native Method) at java.lang.invoke.MemberName$Factory.resolve(java.base@9-internal/MemberName.java:1036) at java.lang.invoke.MemberName$Factory.resolveOrFail(java.base@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

_______________________________________________
mlvm-dev mailing list
mlvm-dev@openjdk.java.net
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev

Reply via email to