import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.io.FastOutput; import org.junit.Test; import java.io.ByteArrayOutputStream; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.ArrayList; public class StackOverflowTest_2_24_0 { @Test public void thisWorks() { FooRef fooRef = new FooRef(); GenericFoo genFoo1 = new GenericFoo<>(fooRef); GenericFoo genFoo2 = new GenericFoo<>(fooRef); List> foos = new ArrayList<>(); // Note the order of the items in the list (vs goBananas) foos.add(genFoo1); foos.add(genFoo2); new FooContainer(foos); Kryo kryo = new Kryo(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); kryo.writeObject(new FastOutput(outputStream), genFoo1); } @Test public void goBananas() { FooRef fooRef = new FooRef(); GenericFoo genFoo1 = new GenericFoo<>(fooRef); GenericFoo genFoo2 = new GenericFoo<>(fooRef); List> foos = new ArrayList<>(); // Note the order of the items in the list (vs thisWorks) foos.add(genFoo2); foos.add(genFoo1); new FooContainer(foos); Kryo kryo = new Kryo(); ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); kryo.writeObject(new FastOutput(outputStream), genFoo1); } } class FooContainer { List> foos; public FooContainer(List> foos) { this.foos = foos; for (GenericFoo foo : foos) { foo.container = this; } } } interface Foo {} class FooRef implements Foo {} class GenericFoo implements Foo { private Map map = Collections.singletonMap("myself", (Object) this); B foo; FooContainer container; public GenericFoo(B foo) { this.foo = foo; } }