-
Bug
-
Resolution: Unresolved
-
P4
-
1.4.2, 8
-
linux
FULL PRODUCT VERSION :
1.8.0-ea-b106
A DESCRIPTION OF THE PROBLEM :
A lambda that captures a value that refers back to that lambda cannot be properly deserialized. This is caused by the usage of readResolve() in java.lang.invoke.SerializedLambda.
ACTUAL -
The cyclic reference is not resolved, an instance of java.lang.invoke.SerializedLambda is used where a lambda is expected.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
first example:
java.lang.ClassCastException: cannot assign instance of java.lang.invoke.SerializedLambda to field SerialLambda.supplier of type SerialLambda$SerializableIntSupplier in instance of SerialLambda
at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2089)
...
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at SerialLambda.serialCopy(SerialLambda.java:32)
at SerialLambda.go(SerialLambda.java:19)
second example:
Exception in thread "main" java.lang.ClassCastException: java.lang.invoke.SerializedLambda cannot be cast to SerialLambda$SerializableIntSupplier
at SerialLambda.lambda$go2$9b75$0(SerialLambda.java:24)
at SerialLambda$$Lambda$2.getAsInt(Unknown Source)
at SerialLambda.go2(SerialLambda.java:26)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.*;
import java.util.*;
import java.util.function.IntSupplier;
/** @author Wouter Coekaerts */
public class SerialLambda implements Serializable {
interface SerializableIntSupplier extends IntSupplier, Serializable {}
public static void main(String[] args) throws Exception {
new SerialLambda().go();
go2();
}
SerializableIntSupplier supplier;
void go() throws Exception {
supplier = this::hashCode;
System.out.println(serialCopy(this).supplier.getAsInt());
System.out.println(serialCopy(this.supplier).getAsInt());
}
static void go2() throws Exception {
List<SerializableIntSupplier> list = new ArrayList<>();
list.add(() -> list.get(0).hashCode());
System.out.println(serialCopy(list).get(0).getAsInt());
System.out.println(serialCopy(list.get(0)).getAsInt());
}
@SuppressWarnings("unchecked")
static <T> T serialCopy(T o) throws Exception {
ByteArrayOutputStream ba = new ByteArrayOutputStream();
new ObjectOutputStream(ba).writeObject(o);
return (T) new ObjectInputStream(new ByteArrayInputStream(ba.toByteArray())).readObject();
}
}
---------- END SOURCE ----------
1.8.0-ea-b106
A DESCRIPTION OF THE PROBLEM :
A lambda that captures a value that refers back to that lambda cannot be properly deserialized. This is caused by the usage of readResolve() in java.lang.invoke.SerializedLambda.
ACTUAL -
The cyclic reference is not resolved, an instance of java.lang.invoke.SerializedLambda is used where a lambda is expected.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
first example:
java.lang.ClassCastException: cannot assign instance of java.lang.invoke.SerializedLambda to field SerialLambda.supplier of type SerialLambda$SerializableIntSupplier in instance of SerialLambda
at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2089)
...
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
at SerialLambda.serialCopy(SerialLambda.java:32)
at SerialLambda.go(SerialLambda.java:19)
second example:
Exception in thread "main" java.lang.ClassCastException: java.lang.invoke.SerializedLambda cannot be cast to SerialLambda$SerializableIntSupplier
at SerialLambda.lambda$go2$9b75$0(SerialLambda.java:24)
at SerialLambda$$Lambda$2.getAsInt(Unknown Source)
at SerialLambda.go2(SerialLambda.java:26)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.*;
import java.util.*;
import java.util.function.IntSupplier;
/** @author Wouter Coekaerts */
public class SerialLambda implements Serializable {
interface SerializableIntSupplier extends IntSupplier, Serializable {}
public static void main(String[] args) throws Exception {
new SerialLambda().go();
go2();
}
SerializableIntSupplier supplier;
void go() throws Exception {
supplier = this::hashCode;
System.out.println(serialCopy(this).supplier.getAsInt());
System.out.println(serialCopy(this.supplier).getAsInt());
}
static void go2() throws Exception {
List<SerializableIntSupplier> list = new ArrayList<>();
list.add(() -> list.get(0).hashCode());
System.out.println(serialCopy(list).get(0).getAsInt());
System.out.println(serialCopy(list.get(0)).getAsInt());
}
@SuppressWarnings("unchecked")
static <T> T serialCopy(T o) throws Exception {
ByteArrayOutputStream ba = new ByteArrayOutputStream();
new ObjectOutputStream(ba).writeObject(o);
return (T) new ObjectInputStream(new ByteArrayInputStream(ba.toByteArray())).readObject();
}
}
---------- END SOURCE ----------
- duplicates
-
JDK-8304814 Cannot assign instance of java.util.CollSer to java.util.List
-
- Closed
-
- relates to
-
JDK-4957674 Hash entries placed into wrong buckets during deserialization
-
- Open
-
-
JDK-6208166 Deserialization fails with cyclic object graph using HashSet
-
- Open
-