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

findVirtual on array classes incorrectly restricts the receiver type

XMLWordPrintable

    • b25
    • generic
    • generic

      A DESCRIPTION OF THE PROBLEM :
      Calling lookup.findVirtual(int[].class, "clone", MethodType.methodType(Object.class)) with a lookup that is not in the package java.lang will give a MethodHandle with the type (<lookup.lookupClass()>)Ljava/lang/Object; instead of ([I)Ljava/lang/Object;

      Using the publicLookup works correctly because its lookupClass is java.lang.Object. This is why the tests added in JDK-8001105 pass.

      https://github.com/openjdk/jdk/blob/c2e3d7284814cd6b49f44b4de18e0f92310422b0/src/java.base/share/classes/java/lang/invoke/MethodHandles.java#L3940

      Additionally, you can use a lookup from Lookup.in(Class) and it will give you a MethodHandle to clone an object that doesn't have a public clone method, or implement Clonable, however this is not particularly useful because JVM_Clone will throw CloneNotSupported if it doesn't implement Clonable

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run the following class

      import java.lang.invoke.MethodHandle;
      import java.lang.invoke.MethodHandles;
      import java.lang.invoke.MethodType;

      class Scratch
      {
      public static void main(String[] args) throws Throwable
      {
      MethodHandles.Lookup lookup = MethodHandles.lookup();
      MethodHandle mh = lookup.findVirtual(int[].class, "clone", MethodType.methodType(Object.class));
      System.out.println(mh.type());
      mh.invoke(new int[]{});
      }
      }


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      it should print `(int[])Object` and complete normally
      ACTUAL -
      it prints `(Scratch)Object` and throws a ClassCastException

      ---------- BEGIN SOURCE ----------
      import java.lang.invoke.MethodHandle;
      import java.lang.invoke.MethodHandles;
      import java.lang.invoke.MethodType;

      class Scratch
      {
      public static void main(String[] args) throws Throwable
      {
      MethodHandles.Lookup lookup = MethodHandles.lookup();
      MethodHandle mh = lookup.findVirtual(int[].class, "clone", MethodType.methodType(Object.class));
      mh.invoke(new int[]{});
      }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Use a publicLookup, or a lookup from a class in java.lang

      FREQUENCY : always


            liach Chen Liang
            webbuggrp Webbug Group
            Votes:
            1 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: