Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7058630

JSR 292 method handle proxy violates contract for Object methods

    XMLWordPrintable

Details

    • b01
    • generic
    • generic
    • Verified

    Backports

      Description

        import java.lang.invoke.*;
        import java.util.Arrays;

        class BadProxy {
            private static void run() {
                System.out.println("hello, world");
            }
            public static void main(String... av) throws Throwable {
                MethodHandles.Lookup lookup = MethodHandles.lookup();
                MethodHandle run = lookup.findStatic(lookup.lookupClass(), "run", MethodType.methodType(void.class));
                Runnable r = MethodHandleProxies.asInterfaceInstance(Runnable.class, run);
                testRunnable(r);
            }
            private static void testRunnable(Runnable r) {
                r.run();
                Object o = r;
                boolean eq = (o == o);
                int hc = System.identityHashCode(o);
                String st = o.getClass().getName() + "@" + Integer.toHexString(hc);
                Object expect = Arrays.asList(st, eq, hc);
                System.out.println("expect st/eq/hc = "+expect);
                Object actual = Arrays.asList(o.toString(), o.equals(o), o.hashCode());
                System.out.println("actual st/eq/hc = "+actual);
                if (!expect.equals(actual)) throw new AssertionError(expect+" != "+actual);
            }
        }
        /*
        Bug:

        hello, world
        expect st/eq/hc = [$Proxy0@58431c, true, 5784348]
        actual st/eq/hc = [java.lang.invoke.MethodHandleProxies$1@9e0c79, false, 10357881]
        Exception in thread "main" java.lang.AssertionError: [$Proxy0@58431c, true, 5784348] != [java.lang.invoke.MethodHandleProxies$1@9e0c79, false, 10357881]
        at BadProxy.testRunnable(BadProxy.java:24)
        at BadProxy.main(BadProxy.java:12)

        Expected:

        hello, world
        expect st/eq/hc = [$Proxy0@db81f3, true, 14385651]
        actual st/eq/hc = [$Proxy0@db81f3, true, 14385651]

        Fix:

        diff --git a/src/share/classes/java/lang/invoke/MethodHandleProxies.java b/src/share/classes/java/lang/invoke/MethodHandleProxies.java
        --- a/src/share/classes/java/lang/invoke/MethodHandleProxies.java
        +++ b/src/share/classes/java/lang/invoke/MethodHandleProxies.java
        @@ -165,7 +165,7 @@
                                 if (method.getDeclaringClass() == WrapperInstance.class)
                                     return getArg(method.getName());
                                 if (isObjectMethod(method))
        - return callObjectMethod(this, method, args);
        + return callObjectMethod(proxy, method, args);
                                 throw new InternalError("bad proxy method: "+method);
                             }
                         }));

        */

        Attachments

          Issue Links

            Activity

              People

                jrose John Rose
                jrose John Rose
                Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: