From 40bcfae309bb2c143517fd56d16204ee1f1ab28f Mon Sep 17 00:00:00 2001 From: Mr14huashao Date: Mon, 31 Aug 2020 11:02:31 +0800 Subject: [PATCH] Add a WARN for extendedFieldName --- .../CompatibleFieldSerializer.java | 19 +++++++++ .../CompatibleFieldSerializerTest.java | 42 +++++++++++++++++++ 2 files changed, 61 insertions(+) diff --git a/src/com/esotericsoftware/kryo/serializers/CompatibleFieldSerializer.java b/src/com/esotericsoftware/kryo/serializers/CompatibleFieldSerializer.java index b6c3c371d..0c8d10ccc 100644 --- a/src/com/esotericsoftware/kryo/serializers/CompatibleFieldSerializer.java +++ b/src/com/esotericsoftware/kryo/serializers/CompatibleFieldSerializer.java @@ -32,6 +32,9 @@ import com.esotericsoftware.kryo.util.ObjectMap; import com.esotericsoftware.kryo.util.Util; +import java.lang.reflect.Field; +import java.util.HashSet; + /** Serializes objects using direct field assignment, providing both forward and backward compatibility. This means fields can be * added or removed without invalidating previously serialized bytes. Renaming or changing the type of a field is not supported. * Like {@link FieldSerializer}, it can serialize most classes without needing annotations. @@ -58,6 +61,22 @@ public CompatibleFieldSerializer (Kryo kryo, Class type, CompatibleFieldSerializ this.config = config; } + @Override + protected void initializeCachedFields() { + if (!super.config.extendedFieldNames) { + final HashSet hashSet = new HashSet(); + CachedField[] fields = cachedFields.fields; + for (int i = 0, n = fields.length; i < n; i++) { + final Field field = fields[i].field; + if (!hashSet.add(field.getName())) { + if (WARN) warn("Detected duplicate field " + field.getName() + " in class hierarchy " + + field.getDeclaringClass() + ". Consider enabling FieldSerializerConfig.extendedFieldNames"); + break; + } + } + } + } + @Override public void write (Kryo kryo, Output output, T object) { int pop = pushTypeVariables(); diff --git a/test/com/esotericsoftware/kryo/serializers/CompatibleFieldSerializerTest.java b/test/com/esotericsoftware/kryo/serializers/CompatibleFieldSerializerTest.java index 829382467..2d00a1b59 100644 --- a/test/com/esotericsoftware/kryo/serializers/CompatibleFieldSerializerTest.java +++ b/test/com/esotericsoftware/kryo/serializers/CompatibleFieldSerializerTest.java @@ -24,17 +24,28 @@ import com.esotericsoftware.kryo.Kryo; import com.esotericsoftware.kryo.KryoException; import com.esotericsoftware.kryo.KryoTestCase; +import com.esotericsoftware.kryo.Serializer; +import com.esotericsoftware.kryo.SerializerFactory; import com.esotericsoftware.kryo.SerializerFactory.CompatibleFieldSerializerFactory; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; import java.io.Serializable; import java.util.Arrays; import java.util.List; import java.util.Objects; +import com.esotericsoftware.kryo.io.Input; +import com.esotericsoftware.kryo.io.Output; +import com.esotericsoftware.kryo.util.DefaultInstantiatorStrategy; import org.apache.commons.lang.builder.EqualsBuilder; +import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.objenesis.strategy.SerializingInstantiatorStrategy; /** @author Nathan Sweet */ public class CompatibleFieldSerializerTest extends KryoTestCase { @@ -642,4 +653,35 @@ public int hashCode () { return Objects.hash(value, list, serializable); } } + + @Test + public void testLogWarningOnDuplicateFieldInClassHierarchy() { + kryo.setReferences(true); + CompatibleFieldSerializer serializer = new CompatibleFieldSerializer(kryo, ClassWithDuplicateField.class); + serializer.getCompatibleFieldSerializerConfig().setChunkedEncoding(true); + serializer.getCompatibleFieldSerializerConfig().setExtendedFieldNames(false); + serializer.updateFields(); + kryo.register(ClassWithDuplicateField.class, serializer); + + final ClassWithDuplicateField duplicateField = new ClassWithDuplicateField(); + roundTrip(31, duplicateField); + + ClassWithDuplicateField object2 = (ClassWithDuplicateField) kryo.readClassAndObject(input); + assertEquals(duplicateField, object2); + } + + static class ClassWithDuplicateField extends SuperClassWithDuplicateField { + private Boolean customNote = true; + } + + static class SuperClassWithDuplicateField implements Serializable { + private Boolean customNote = false; + + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj == null) return false; + if (getClass() != obj.getClass()) return false; + return true; + } + } }