EsotericSoftware / EsotericSoftware/kryo

ExternalizableSerializer does not support circular references

Open
#1,094 2 comments 0 reactions 0 assignees View on GitHub
bug help wanted
Dominant language
HTML
Stars
6.5k
Forks
841
Avg merge
39m
Merged PRs (30d)
4

Description

**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

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.