diff --git a/src/main/java/net/openhft/chronicle/wire/WireMarshaller.java b/src/main/java/net/openhft/chronicle/wire/WireMarshaller.java index a2c5d5c85c..8a5d34ada7 100644 --- a/src/main/java/net/openhft/chronicle/wire/WireMarshaller.java +++ b/src/main/java/net/openhft/chronicle/wire/WireMarshaller.java @@ -1563,6 +1563,8 @@ else if (type == Set.class) componentType = extractClass(computeActualTypeArguments(Collection.class, field)[0]); if (componentType != Object.class) { isLeaf = !Throwable.class.isAssignableFrom(componentType) + // Don't recurse into the same class + && !componentType.equals(field.getDeclaringClass()) && WIRE_MARSHALLER_CL.get(componentType).isLeaf; } diff --git a/src/test/java/net/openhft/chronicle/wire/recursive/Base.java b/src/test/java/net/openhft/chronicle/wire/recursive/Base.java new file mode 100644 index 0000000000..9237ee7a9b --- /dev/null +++ b/src/test/java/net/openhft/chronicle/wire/recursive/Base.java @@ -0,0 +1,15 @@ +package net.openhft.chronicle.wire.recursive; + +import net.openhft.chronicle.wire.AbstractEventCfg; + +public class Base extends AbstractEventCfg<Base> { + private final String name; + + public Base(String name) { + this.name = name; + } + + public String name() { + return name; + } +} diff --git a/src/test/java/net/openhft/chronicle/wire/recursive/RecursiveTest.java b/src/test/java/net/openhft/chronicle/wire/recursive/RecursiveTest.java new file mode 100644 index 0000000000..dba5bd58ad --- /dev/null +++ b/src/test/java/net/openhft/chronicle/wire/recursive/RecursiveTest.java @@ -0,0 +1,42 @@ +package net.openhft.chronicle.wire.recursive; + +import net.openhft.chronicle.wire.WireMarshaller; +import org.junit.Test; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +/** + * Test for recursion in the marshaller and fields. WIRE_MARSHALLER_CL.get should not recurse while + * looking up fields of the class. At time of writing this occurs when checking if the component class + * of a subfield is a leaf and is only a problem when the component class is the same as the parent class. + */ +public class RecursiveTest { + + @Test + public void referToBaseClass() { + test(new ReferToBaseClass("hello"), new ReferToBaseClass(null)); + } + + @Test + public void referToSameClass() { + test(new ReferToSameClass("test"), new ReferToSameClass(null)); + } + + @Test + public void marshallerReferToSameClass() { + WireMarshaller<?> marshaller= WireMarshaller.WIRE_MARSHALLER_CL.get(ReferToSameClass.class); + assertNotNull(marshaller); + } + + @Test + public void marshallerReferToBaseClass() { + WireMarshaller<?> marshaller = WireMarshaller.WIRE_MARSHALLER_CL.get(ReferToBaseClass.class); + assertNotNull(marshaller); + } + + private void test(Base from, Base to) { + from.copyTo(to); + assertEquals(from.name(), to.name()); + } +} \ No newline at end of file diff --git a/src/test/java/net/openhft/chronicle/wire/recursive/ReferToBaseClass.java b/src/test/java/net/openhft/chronicle/wire/recursive/ReferToBaseClass.java new file mode 100644 index 0000000000..e291508112 --- /dev/null +++ b/src/test/java/net/openhft/chronicle/wire/recursive/ReferToBaseClass.java @@ -0,0 +1,16 @@ +package net.openhft.chronicle.wire.recursive; + +import java.util.ArrayList; +import java.util.List; + +public class ReferToBaseClass extends ReferToSameClass { + private final List<ReferToSameClass> list = new ArrayList<>(); + + public ReferToBaseClass(String name) { + super(name); + } + + public List<ReferToSameClass> list() { + return list; + } +} diff --git a/src/test/java/net/openhft/chronicle/wire/recursive/ReferToSameClass.java b/src/test/java/net/openhft/chronicle/wire/recursive/ReferToSameClass.java new file mode 100644 index 0000000000..57d4832a0e --- /dev/null +++ b/src/test/java/net/openhft/chronicle/wire/recursive/ReferToSameClass.java @@ -0,0 +1,16 @@ +package net.openhft.chronicle.wire.recursive; + +import java.util.ArrayList; +import java.util.List; + +public class ReferToSameClass extends Base { + private final List<ReferToSameClass> list = new ArrayList<>(); + + public ReferToSameClass(String name) { + super(name); + } + + public List<ReferToSameClass> list() { + return list; + } +}