EsotericSoftware/kryo

ExternalizableSerializer does not support circular references

开放

#1,094 创建于 2024年6月21日

 (2 条评论) (0 个反应) (0 位负责人)HTML (839 个派生)batch import
bughelp wanted

仓库指标

星标
 (6,545 个星标)
PR 合并指标
 (平均合并 107天 5小时) (30 天内合并 9 个 PR)

描述

Describe the bug

If an object implements Externalizable and is registered with the ExternalizableSerializer, there is no way for it to call kryo.reference() on itself and the ExternalizableSerializer doesn't do this either. As a consequence, if the Externalizable attempts to read a reference to itself, it will get null and deserialize incorrectly.

To Reproduce

Provide a minimal reproducible example of the problem, ideally in the form of a runnable test-case.

import com.esotericsoftware.kryo.Kryo;
import com.esotericsoftware.kryo.io.Input;
import com.esotericsoftware.kryo.io.Output;
import com.esotericsoftware.kryo.serializers.ExternalizableSerializer;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;

public class ExternalizableBugProof {
    static class Example implements Externalizable {

        @Override
        public void writeExternal(ObjectOutput out) throws IOException {
            out.writeUTF("abc");
            out.writeObject(this);
        }

        @Override
        public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
            in.readUTF();
            Object obj = in.readObject();
            assert obj == this : "" + obj;
        }
    }

    public static void main(String[] args) {
        var kryo = new Kryo();
        kryo.setReferences(true);
        kryo.setRegistrationRequired(false);
        kryo.addDefaultSerializer(ExternalizableBugProof.Example.class, ExternalizableSerializer.class);

        var output = new Output(1024);
        kryo.writeObject(output, new Example());
        kryo.readObject(new Input(output.getBuffer()), Example.class);
    }
}

Environment:

Kryo 5.6.0

贡献者指南