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

MethodHandleProxies.asInterfaceInstance does not support default methods

    Details

    • Subcomponent:
    • Understanding:
      Fix Understood
    • CPU:
      generic
    • OS:
      generic

      Description

      A DESCRIPTION OF THE PROBLEM :
      Calling a default method on an instance produced by MethodHandleProxies.asInterface throws a " java.lang.InternalError: bad proxy method: ...

      This is a bug because it violates the contract of the default methods, e.g. java.util.Comparator.reversed().
      Passing an interface with default methods is supported, as indicated in the documentation of MethodHandleProxies.asInterface, which mentions java.util.Comparator as example.

      Therefore it is exprected that the resulting instance follows the contract of the default method, which could be done by calling the default implementation of that default method.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create an instance of an interface with at least one default method using MethodHandleProxies.asInterface(Class, MethodHandle).
      Call a default method on that instance.


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      No exception is thrown.
      ACTUAL -
      An exception is thrown.

      Exception in thread "main" java.lang.InternalError: bad proxy method: public default java.util.Comparator java.util.Comparator.reversed()
      at java.lang.invoke.MethodHandleStatics.newInternalError(MethodHandleStatics.java:124)
      at java.lang.invoke.MethodHandleProxies$1.invoke(MethodHandleProxies.java:193)
      at com.sun.proxy.$Proxy0.reversed(Unknown Source)
      at bug.BugMain.main(BugMain.java:15)

      ---------- BEGIN SOURCE ----------
      package bug;

      import java.lang.invoke.MethodHandle;
      import java.lang.invoke.MethodHandleProxies;
      import java.lang.invoke.MethodHandles;
      import java.util.Comparator;

      public class BugMain {
      public static void main(String[] args) {
      MethodHandle const0 = MethodHandles.constant(int.class, 0);
      MethodHandle compH = MethodHandles.dropArguments(const0, 0, Object.class, Object.class);
      Comparator<?> cmp = MethodHandleProxies.asInterfaceInstance(Comparator.class, compH);
      // cmp = (a, b) -> 0;
      cmp.reversed();
      }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use the LambdaMetaFactory. This might not work for all cases and is more complicated than the simple MethodHandleProxy.

      FREQUENCY : always


        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                psandoz Paul Sandoz
                Reporter:
                webbuggrp Webbug Group
              • Votes:
                0 Vote for this issue
                Watchers:
                3 Start watching this issue

                Dates

                • Created:
                  Updated: