Hi,
I have created a custom implementation of the java.util.Map that is to be used by others as a library and I want that to be serializable with Kryo.
The problem I have is that if I define my class to implement KryoSerializable I expect Kryo to use the specified write and read methods for the (de)serialization.
The problem I have is that it doesn't : it uses the more generic MapSerializer instead and as a consequence I get NPE.
My question to you: What have I done wrong; or is this a bug in Kryo ?
I have been able to reproduce this effect to this:
I'm using this dependency in my project:
<dependency>
<groupId>com.esotericsoftware</groupId>
<artifactId>kryo</artifactId>
<version>5.0.0-RC9</version>
<scope>provided</scope>
</dependency>
and I have defined my Map as (short version)
public class MyCustomMap<V extends Serializable> implements Map<String, V>, KryoSerializable, Serializable {
private Boolean someFlag;
private TreeMap<String, V> stuff;
private MyCustomMap() {
}
public MyCustomMap(boolean newSomeFlag) {
someFlag = newSomeFlag;
stuff = new TreeMap<>();
}
@Override
public void write(Kryo kryo, Output output) {
output.writeBoolean(someFlag);
kryo.writeClassAndObject(output, stuff);
}
@Override
@SuppressWarnings("unchecked")
public void read(Kryo kryo, Input input) {
someFlag = input.readBoolean();
stuff = (TreeMap<String, V>) kryo.readClassAndObject(input);
}
....
}
Then in a test I do this
Kryo kryo = new Kryo();
kryo.register(MyCustomMap.class);
ByteBufferOutput byteBufferOutput = new ByteBufferOutput(1_000_000, -1);
kryo.writeClassAndObject(byteBufferOutput, instance);
ByteBuffer bytes = byteBufferOutput.getByteBuffer();
bytes.rewind();
ByteBufferInput byteBufferInput = new ByteBufferInput(bytes);
Object mapObject = kryo.readClassAndObject(byteBufferInput);
This is the stacktrace I get seems to indicate that it isn't using the write/read I specified but the more generic MapSerializer instead.
java.lang.NullPointerException
at nl.basjes....@2.0-SNAPSHOT/nl.basjes.collections.MyCustomMap.put(MyCustomMap.java:64)
at nl.basjes....@2.0-SNAPSHOT/nl.basjes.collections.MyCustomMap.put(MyCustomMap.java:31)
at com.esoteric...@5.0.0-RC9/com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:238)
at com.esoteric...@5.0.0-RC9/com.esotericsoftware.kryo.serializers.MapSerializer.read(MapSerializer.java:42)
at com.esoteric...@5.0.0-RC9/com.esotericsoftware.kryo.Kryo.readClassAndObject(Kryo.java:809)
at nl.basjes....@2.0-SNAPSHOT/nl.basjes.collections.MyCustomMapTest.testKyroSerialization(MyCustomMapTest.java:69)
Niels Basjes