-
Bug
-
Resolution: Fixed
-
P4
-
8, 11, 17, 19, 20
-
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 inJDK-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
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
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