-
Bug
-
Resolution: Fixed
-
P4
-
17
-
b24
-
Verified
A DESCRIPTION OF THE PROBLEM :
I'd like to provide a reproducible forJDK-8304814. Under the hood java.lang.ClassCastException: Cannot cast java.util.CollSer hides ClassNotFoundException. It can be easily reproduced with both Class or Record that reference an immutable map that contains objects of missing classes.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Serialise data to file : java TestClassCastException write
2. rm DeletedClass.class
3. Read file java TestClassCastException read
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
java.lang.ClassNotFoundException
ACTUAL -
For classes it throws Exception in thread "main" java.lang.ClassCastException: cannot assign instance of java.util.CollSer to field TestClassCastException$C.data of type java.util.Map in instance of TestClassCastException$C at java.base/java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2096) at java.base/java.io.ObjectStreamClass$FieldReflector.checkObjectFieldValueTypes(ObjectStreamClass.java:2060) at java.base/java.io.ObjectStreamClass.checkObjFieldValueTypes(ObjectStreamClass.java:1347) at java.base/java.io.ObjectInputStream$FieldValues.defaultCheckFieldValues(ObjectInputStream.java:2679) at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2486) at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2257) at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1733) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:509) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:467) at TestClassCastException.read(TestClassCastException.java:40) at TestClassCastException.main(TestClassCastException.java:24)
For records it throwsException in thread "main" java.io.InvalidObjectException: Cannot cast java.util.CollSer to java.util.Map at java.base/java.io.ObjectInputStream.readRecord(ObjectInputStream.java:2363) at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2251) at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1733) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:509) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:467) at TestClassCastException.read(TestClassCastException.java:41) at TestClassCastException.main(TestClassCastException.java:22)Caused by: java.lang.ClassCastException: Cannot cast java.util.CollSer to java.util.Map at java.base/java.lang.Class.cast(Class.java:3889) at java.base/java.io.ObjectInputStream.readRecord(ObjectInputStream.java:2361) ... 6 more
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
public class TestClassCastException {
public static void main(String[] args) throws Exception {
File f = new File("/tmp/write.ser");
if (args.length > 0 && args[0].equals("write")){
Map m = Map.of("key", new DeletedClass());
TestClassCastException.R r = new TestClassCastException.R(m);
f.delete();
write(new FileOutputStream(f), r);
} else{
read(new FileInputStream(f));
}
}
public record R(Map<String, Map> data) implements Serializable {
}
private static void read(InputStream str) throws Exception {
try (ObjectInputStream ois = new ObjectInputStream(str)) {
Object o = ois.readObject();
System.out.println(o);
}
}
private static void write(OutputStream os, Object o) throws Exception {
try (ObjectOutputStream os2 = new ObjectOutputStream(os)) {
os2.writeObject(o);
}
}
}
import java.io.Serializable;
public class DeletedClass implements Serializable {
}
---------- END SOURCE ----------
FREQUENCY : always
I'd like to provide a reproducible for
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Serialise data to file : java TestClassCastException write
2. rm DeletedClass.class
3. Read file java TestClassCastException read
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
java.lang.ClassNotFoundException
ACTUAL -
For classes it throws Exception in thread "main" java.lang.ClassCastException: cannot assign instance of java.util.CollSer to field TestClassCastException$C.data of type java.util.Map in instance of TestClassCastException$C at java.base/java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2096) at java.base/java.io.ObjectStreamClass$FieldReflector.checkObjectFieldValueTypes(ObjectStreamClass.java:2060) at java.base/java.io.ObjectStreamClass.checkObjFieldValueTypes(ObjectStreamClass.java:1347) at java.base/java.io.ObjectInputStream$FieldValues.defaultCheckFieldValues(ObjectInputStream.java:2679) at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2486) at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2257) at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1733) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:509) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:467) at TestClassCastException.read(TestClassCastException.java:40) at TestClassCastException.main(TestClassCastException.java:24)
For records it throwsException in thread "main" java.io.InvalidObjectException: Cannot cast java.util.CollSer to java.util.Map at java.base/java.io.ObjectInputStream.readRecord(ObjectInputStream.java:2363) at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2251) at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1733) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:509) at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:467) at TestClassCastException.read(TestClassCastException.java:41) at TestClassCastException.main(TestClassCastException.java:22)Caused by: java.lang.ClassCastException: Cannot cast java.util.CollSer to java.util.Map at java.base/java.lang.Class.cast(Class.java:3889) at java.base/java.io.ObjectInputStream.readRecord(ObjectInputStream.java:2361) ... 6 more
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.util.LinkedHashMap;
import java.util.Map;
public class TestClassCastException {
public static void main(String[] args) throws Exception {
File f = new File("/tmp/write.ser");
if (args.length > 0 && args[0].equals("write")){
Map m = Map.of("key", new DeletedClass());
TestClassCastException.R r = new TestClassCastException.R(m);
f.delete();
write(new FileOutputStream(f), r);
} else{
read(new FileInputStream(f));
}
}
public record R(Map<String, Map> data) implements Serializable {
}
private static void read(InputStream str) throws Exception {
try (ObjectInputStream ois = new ObjectInputStream(str)) {
Object o = ois.readObject();
System.out.println(o);
}
}
private static void write(OutputStream os, Object o) throws Exception {
try (ObjectOutputStream os2 = new ObjectOutputStream(os)) {
os2.writeObject(o);
}
}
}
import java.io.Serializable;
public class DeletedClass implements Serializable {
}
---------- END SOURCE ----------
FREQUENCY : always
- relates to
-
JDK-8304814 Cannot assign instance of java.util.CollSer to java.util.List
-
- Closed
-
- links to
-
Commit openjdk/jdk/8291c94b
-
Review(master) openjdk/jdk/19043