From a5909b04f165684ee9f96ce972764d6515d3ad9b Mon Sep 17 00:00:00 2001 From: Leif Åstrand Date: Mon, 23 Jan 2017 15:52:54 +0200 Subject: Fix BeanBinderPropertySet to not deserialize into multiple instances (#8305) * Fix BeanBinderPropertySet to not deserialize into multiple instances --- .../com/vaadin/data/BeanBinderPropertySetTest.java | 73 ++++++++++++++++++---- .../tests/server/ClassesSerializableTest.java | 11 +++- 2 files changed, 71 insertions(+), 13 deletions(-) (limited to 'server/src/test') diff --git a/server/src/test/java/com/vaadin/data/BeanBinderPropertySetTest.java b/server/src/test/java/com/vaadin/data/BeanBinderPropertySetTest.java index d11541fb0c..1fa431ac20 100644 --- a/server/src/test/java/com/vaadin/data/BeanBinderPropertySetTest.java +++ b/server/src/test/java/com/vaadin/data/BeanBinderPropertySetTest.java @@ -19,34 +19,83 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; +import java.lang.reflect.Field; +import java.util.Map; import org.junit.Assert; import org.junit.Test; import com.vaadin.data.provider.bov.Person; +import com.vaadin.tests.server.ClassesSerializableTest; public class BeanBinderPropertySetTest { @Test - public void testSerializeDeserialize() throws Exception { - BinderPropertyDefinition definition = BeanBinderPropertySet - .get(Person.class).getProperty("born") - .orElseThrow(RuntimeException::new); + public void testSerializeDeserialize_propertySet() throws Exception { + BinderPropertySet originalPropertySet = BeanBinderPropertySet + .get(Person.class); - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream out = new ObjectOutputStream(bos); - out.writeObject(definition); - out.flush(); + BinderPropertySet deserializedPropertySet = ClassesSerializableTest + .serializeAndDeserialize(originalPropertySet); - ObjectInputStream inputStream = new ObjectInputStream( - new ByteArrayInputStream(bos.toByteArray())); + Assert.assertSame( + "Deserialized instance should be the same as the original", + originalPropertySet, deserializedPropertySet); + } - BinderPropertyDefinition deserializedDefinition = (BinderPropertyDefinition) inputStream + @Test + public void testSerializeDeserialize_propertySet_cacheCleared() + throws Exception { + BinderPropertySet originalPropertySet = BeanBinderPropertySet + .get(Person.class); + + ByteArrayOutputStream bs = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(bs); + out.writeObject(originalPropertySet); + byte[] data = bs.toByteArray(); + + // Simulate deserializing into a different JVM by clearing the instance + // map + Field instancesField = BeanBinderPropertySet.class + .getDeclaredField("instances"); + instancesField.setAccessible(true); + Map instances = (Map) instancesField.get(null); + instances.clear(); + + ObjectInputStream in = new ObjectInputStream( + new ByteArrayInputStream(data)); + BinderPropertySet deserializedPropertySet = (BinderPropertySet) in .readObject(); + Assert.assertSame( + "Deserialized instance should be the same as in the cache", + BeanBinderPropertySet.get(Person.class), + deserializedPropertySet); + Assert.assertNotSame( + "Deserialized instance should not be the same as the original", + originalPropertySet, deserializedPropertySet); + } + + @Test + public void testSerializeDeserialize_propertyDefinition() throws Exception { + BinderPropertyDefinition definition = BeanBinderPropertySet + .get(Person.class).getProperty("born") + .orElseThrow(RuntimeException::new); + + BinderPropertyDefinition deserializedDefinition = ClassesSerializableTest + .serializeAndDeserialize(definition); + ValueProvider getter = deserializedDefinition.getGetter(); Person person = new Person("Milennial", 2000); Integer age = (Integer) getter.apply(person); - Assert.assertEquals(Integer.valueOf(2000), age); + Assert.assertEquals("Deserialized definition should be functional", + Integer.valueOf(2000), age); + + Assert.assertSame( + "Deserialized instance should be the same as in the cache", + BeanBinderPropertySet.get(Person.class).getProperty("born") + .orElseThrow(RuntimeException::new), + deserializedDefinition); } + } diff --git a/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java b/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java index 8a97e2217c..fca87ccbdf 100644 --- a/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java +++ b/server/src/test/java/com/vaadin/tests/server/ClassesSerializableTest.java @@ -185,13 +185,22 @@ public class ClassesSerializableTest { } defaultCtor.get().setAccessible(true); Object instance = defaultCtor.get().newInstance(); + serializeAndDeserialize(instance); + } + + public static T serializeAndDeserialize(T instance) + throws IOException, ClassNotFoundException { ByteArrayOutputStream bs = new ByteArrayOutputStream(); ObjectOutputStream out = new ObjectOutputStream(bs); out.writeObject(instance); byte[] data = bs.toByteArray(); ObjectInputStream in = new ObjectInputStream( new ByteArrayInputStream(data)); - in.readObject(); + + @SuppressWarnings("unchecked") + T readObject = (T) in.readObject(); + + return readObject; } private void failSerializableFields( -- cgit v1.2.3