EsotericSoftware / EsotericSoftware/kryo
ExternalizableSerializer does not support circular references
- 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
Assessment
This issue has not been assessed yet.