Repository: movingblocks/terasology
Issue: Serialization stack overflow

The game crashed with a stack overflow error. The stack trace was the following, repeated many times:

	at org.terasology.persistence.typeHandling.FutureTypeHandler.serialize(FutureTypeHandler.java:32)
	at org.terasology.persistence.typeHandling.coreTypes.RuntimeDelegatingTypeHandler.serializeViaDelegate(RuntimeDelegatingTypeHandler.java:162)
	at org.terasology.persistence.typeHandling.coreTypes.RuntimeDelegatingTypeHandler.serializeNonNull(RuntimeDelegatingTypeHandler.java:118)
	at org.terasology.persistence.typeHandling.TypeHandler.serialize(TypeHandler.java:49)
	at org.terasology.persistence.typeHandling.coreTypes.ObjectFieldMapTypeHandler.serializeNonNull(ObjectFieldMapTypeHandler.java:71)
	at org.terasology.persistence.typeHandling.TypeHandler.serialize(TypeHandler.java:49)

It ran for a minute or so before this happened, using much more CPU than usual (but this was probably just the ocean falling into caves). I was using JS + FlowingLiquids (and some almost certainly irrelevant changes that would never have even executed under the circumstances).

I haven't been able to replicate it in any other worlds, and I can't load the one where I originally saw it because chunk generation times out.

Changed files:
engine/src/main/java/org/terasology/particles/components/ParticleEmitterComponent.java
engine/src/main/java/org/terasology/persistence/typeHandling/coreTypes/ObjectFieldMapTypeHandler.java

diff --git a/engine/src/main/java/org/terasology/particles/components/ParticleEmitterComponent.java b/engine/src/main/java/org/terasology/particles/components/ParticleEmitterComponent.java
index 3e974f550..212e9006c 100644
--- a/engine/src/main/java/org/terasology/particles/components/ParticleEmitterComponent.java
+++ b/engine/src/main/java/org/terasology/particles/components/ParticleEmitterComponent.java
@@ -94,7 +94,7 @@ public class ParticleEmitterComponent implements Component {
     /**
      * This emitter's particle pool.
      */
-    public ParticlePool particlePool;
+    public transient ParticlePool particlePool;
 
     /**
      * Maps Generator component -> Function that processes that Generator
diff --git a/engine/src/main/java/org/terasology/persistence/typeHandling/coreTypes/ObjectFieldMapTypeHandler.java b/engine/src/main/java/org/terasology/persistence/typeHandling/coreTypes/ObjectFieldMapTypeHandler.java
index 2ae9261e8..b524383b7 100644
--- a/engine/src/main/java/org/terasology/persistence/typeHandling/coreTypes/ObjectFieldMapTypeHandler.java
+++ b/engine/src/main/java/org/terasology/persistence/typeHandling/coreTypes/ObjectFieldMapTypeHandler.java
@@ -68,9 +68,14 @@ public PersistedData serializeNonNull(T value, PersistedDataSerializer serialize
 
             if (!Objects.equals(val, Defaults.defaultValue(field.getType()))) {
                 TypeHandler handler = entry.getValue();
-                PersistedData fieldValue = handler.serialize(val, serializer);
-                if (fieldValue != null) {
-                    mappedData.put(getFieldName(field), fieldValue);
+                try {
+                    PersistedData fieldValue = handler.serialize(val, serializer);
+                    if (fieldValue != null) {
+                        mappedData.put(getFieldName(field), fieldValue);
+                    }
+                } catch (StackOverflowError e) {
+                    logger.error("Likely circular reference in field {}.", field);
+                    throw e;
                 }
             }
         }