EsotericSoftware / kryo

Java binary serialization and cloning: fast, efficient, automatic
BSD 3-Clause "New" or "Revised" License
6.19k stars 823 forks source link

`java.lang.ArrayIndexOutOfBoundsException: 1` #860

Closed catap closed 2 years ago

catap commented 2 years ago

Describe the bug

Kryo can't serialize fastutils' structures with error: java.lang.ArrayIndexOutOfBoundsException: 1.

To Reproduce

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Output;

import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;

import java.io.ByteArrayOutputStream;

public class Bug {
    private static class Node {
        public Int2ObjectMap<Object> kids;
    }

    public static void main(String[] args) {
        Node node1 = new Node();
        Node node2 = new Node();

        node1.kids = new Int2ObjectArrayMap<>();
        node1.kids.put(1, node2);

        Kryo kryo = new Kryo();

        kryo.setRegistrationRequired(false);

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try (Output output = new Output(bos)) {
            kryo.writeClassAndObject(output, node1);
        }
    }
}

fails as:

Exception in thread "main" com.esotericsoftware.kryo.KryoException: java.lang.ArrayIndexOutOfBoundsException: 1
Serialization trace:
kids (Bug$Node)
    at com.esotericsoftware.kryo.serializers.ReflectField.write(ReflectField.java:101)
    at com.esotericsoftware.kryo.serializers.FieldSerializer.write(FieldSerializer.java:108)
    at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:711)
    at Bug.main(Bug.java:27)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 1
    at com.esotericsoftware.kryo.serializers.MapSerializer.write(MapSerializer.java:140)
    at com.esotericsoftware.kryo.serializers.MapSerializer.write(MapSerializer.java:42)
    at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:642)
    at com.esotericsoftware.kryo.serializers.ReflectField.write(ReflectField.java:70)
    ... 3 more

Environment:

theigl commented 2 years ago

@catap: Kryo has buit-in support for most JDK data structures, but needs help (i.e. a custom serializer) when serializing complex third-party data structures.

Please take a look at https://github.com/magro/kryo-serializers/issues/76. The linked serializer might help, or you can always fall back to plain Java serialization.

catap commented 2 years ago

@theigl or use FieldSerializer which works very well :)

theigl commented 2 years ago

@catap: I would suggest you do some performance tests. If fastutil has optimized custom serialization logic it might be faster and/or smaller than FieldSerializer. But good to know that this works for you!