EsotericSoftware / EsotericSoftware/kryo
Deserialization fails with "Unable to read unknown data" after removing a field with Collection type from the class (Issue with backward compatibility)
- Dominant language
- HTML
- Stars
- 6.5k
- Forks
- 841
- Avg merge
- 39m
- Merged PRs (30d)
- 4
Description
Got KryoException: _ClassNotFoundException(with Maps) /Encountered unregistered class ID(with Lists)_
when I try to deserialize data after removing a field with Collection type from the class.
### **To Reproduce**
**_With Map:_**
First, serialize the original object.
```java
public static class TestClass {
String value;
Map map; //Comment during deserialization
}
```
```java
public static void serialize() throws IOException {
String someString = "some string";
Map map = new LinkedHashMap<>();
map.put(1111, someString);
map.put(2222, someString);
TestClass testClass = new TestClass();
testClass.value = someString;
testClass.map = map;
final File classSerialized =
new File(TEST_RESOURCES_PATH + "/serializedObj.exj");
//This internally calls [writeObject(Output output, Object object)](https://github.com/EsotericSoftware/kryo/blob/master/src/com/esotericsoftware/kryo/Kryo.java#L620) and puts serialized data in a file
writeObject(testClass, classSerialized, serializer);
}
```
Then, comment field map, and run
```java
@Test
public void test_deserialize() {
final File classSerialized =
new File(TEST_RESOURCES_PATH + "/serializedObj.exj");
//This reads from the serialized file and internally calls [readObject (Input input, Class type)](https://github.com/EsotericSoftware/kryo/blob/master/src/com/esotericsoftware/kryo/Kryo.java#L765)
TestClass testClass = readObject(classSerialized, serializer);
assertNotNull(testClass);
assertEquals("some string", testClass.value);
}
```
Got
```
com.esotericsoftware.kryo.kryo5.KryoException: Unable to read unknown data, type: java.util.LinkedHashMap (TestClass#null)
at com.esotericsoftware.kryo.kryo5.serializers.CompatibleFieldSerializer.read(CompatibleFieldSerializer.java:153)
at com.esotericsoftware.kryo.kryo5.serializers.CompatibleFieldSerializer.read(CompatibleFieldSerializer.java:153)
... 75 more
Caused by: java.lang.ClassNotFoundException: ��\ at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
```
**_With List:_**
First, serialize the original object.
```java
public static class TestClass {
String value;
List id; //Comment during deserialization
}
```
```java
public static void serialize() throws IOException {
String someString = "some string";
List id = new ArrayList<>();
list.add(1111L);
list.add(2222L);
TestClass testClass = new TestClass();
testClass.value = someString;
testClass.id = id;
final File classSerialized =
new File(TEST_RESOURCES_PATH + "/serializedObj.exj");
//This internally calls [writeObject(Output output, Object object)](https://github.com/EsotericSoftware/kryo/blob/master/src/com/esotericsoftware/kryo/Kryo.java#L620) and puts serialized data in a file
writeObject(testClass, classSerialized, serializer);
}
```
Then, comment field id, and run
```java
@Test
public void test_deserialize() {
final File classSerialized =
new File(TEST_RESOURCES_PATH + "/serializedObj.exj");
//This reads from the serialized file and internally calls [readObject (Input input, Class type)](https://github.com/EsotericSoftware/kryo/blob/master/src/com/esotericsoftware/kryo/Kryo.java#L765)
TestClass testClass = readObject(classSerialized, serializer);
assertNotNull(testClass);
assertEquals("some string", testClass.value);
}
```
Got
```
com.esotericsoftware.kryo.kryo5.KryoException: Unable to read unknown data, type: java.util.ArrayList (TestClass#null)
... 70 more
Caused by: com.esotericsoftware.kryo.kryo5.KryoException: Encountered unregistered class ID: 2466
```
### **Additional context**
When we try out the same with _**Kryo version 2.24.0**_, it works fine and deserializes properly. However, the same fails with _**Kryo version 5.3.0.**_
FYI, the config looks like this -
```java
kryo.register(KryoWrapper.class);
kryo.setDefaultSerializer(CompatibleFieldSerializer.class);
kryo.setRegistrationRequired(false);
kryo.setReferences(true);
kryo.setOptimizedGenerics(true);
kryo.setInstantiatorStrategy(new DefaultInstantiatorStrategy(new StdInstantiatorStrategy()));
```
I learned that the problem can be solved with _config.setChunkedEncoding(true);_
However, I noticed it doesn't throw any error even with non-passive changes like changing data type of a field. We want to avoid that.
Is there any other thing that can be done to solve the problem? Thank you in advance!
Contributor guide
Assessment
This issue has not been assessed yet.