diff options
author | Artur Signell <artur@vaadin.com> | 2015-10-09 23:44:47 +0300 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2015-11-12 10:54:33 +0000 |
commit | f3eb1b4383848e28447717502083439d9e0dc0b7 (patch) | |
tree | bb81ac60f1b98ef3ea5121a62908b60a14ba4318 /server | |
parent | 142f7dcebb249c9c458cdbade014212b1a9ac27d (diff) | |
download | vaadin-framework-f3eb1b4383848e28447717502083439d9e0dc0b7.tar.gz vaadin-framework-f3eb1b4383848e28447717502083439d9e0dc0b7.zip |
Do not modify state while serializing (#19090)
Serializing an object should never modify its internal state.
It should be possible to serialize an object multiple times and get
the same result
Change-Id: I983e2eec1b3fb374bf40f150bdb9918ac5791d62
Diffstat (limited to 'server')
-rw-r--r-- | server/src/com/vaadin/server/ClientMethodInvocation.java | 9 | ||||
-rw-r--r-- | server/tests/src/com/vaadin/tests/server/ClientMethodSerializationTest.java | 30 |
2 files changed, 37 insertions, 2 deletions
diff --git a/server/src/com/vaadin/server/ClientMethodInvocation.java b/server/src/com/vaadin/server/ClientMethodInvocation.java index 33b88a168b..77849c83df 100644 --- a/server/src/com/vaadin/server/ClientMethodInvocation.java +++ b/server/src/com/vaadin/server/ClientMethodInvocation.java @@ -38,7 +38,7 @@ public class ClientMethodInvocation implements Serializable, private final ClientConnector connector; private final String interfaceName; private final String methodName; - private final Object[] parameters; + private transient Object[] parameters; private Type[] parameterTypes; // used for sorting calls between different connectors in the same UI @@ -102,6 +102,7 @@ public class ClientMethodInvocation implements Serializable, // that is Serializable. On deserialization (readObject-method below) // the process should be reversed. + Object[] serializedParameters = new Object[parameters.length]; // Easy way for implementing serialization & deserialization is by // writing/parsing the object's content as string. for (int i = 0; i < parameterTypes.length; i++) { @@ -109,12 +110,15 @@ public class ClientMethodInvocation implements Serializable, if (type instanceof Class<?>) { Class<?> clazz = (Class<?>) type; if (JsonArray.class.isAssignableFrom(clazz)) { - parameters[i] = JsonUtil + serializedParameters[i] = JsonUtil .stringify((JsonArray) parameters[i]); + } else { + serializedParameters[i] = parameters[i]; } } } stream.defaultWriteObject(); + stream.writeObject(serializedParameters); } private void readObject(ObjectInputStream stream) throws IOException, @@ -122,6 +126,7 @@ public class ClientMethodInvocation implements Serializable, // Reverses the serialization done in writeObject. Basically just // parsing the serialized type back to the non-serializable type. stream.defaultReadObject(); + parameters = (Object[]) stream.readObject(); for (int i = 0; i < parameterTypes.length; i++) { Type type = parameterTypes[i]; if (type instanceof Class<?>) { diff --git a/server/tests/src/com/vaadin/tests/server/ClientMethodSerializationTest.java b/server/tests/src/com/vaadin/tests/server/ClientMethodSerializationTest.java index da6bc76a0f..1ec19724d8 100644 --- a/server/tests/src/com/vaadin/tests/server/ClientMethodSerializationTest.java +++ b/server/tests/src/com/vaadin/tests/server/ClientMethodSerializationTest.java @@ -24,13 +24,16 @@ import java.lang.reflect.Method; import junit.framework.TestCase; +import com.vaadin.server.ClientConnector; import com.vaadin.server.ClientMethodInvocation; import com.vaadin.server.JavaScriptCallbackHelper; +import com.vaadin.server.JsonCodec; import com.vaadin.ui.JavaScript.JavaScriptCallbackRpc; import com.vaadin.util.ReflectTools; import elemental.json.Json; import elemental.json.JsonArray; +import elemental.json.JsonValue; import elemental.json.impl.JsonUtil; public class ClientMethodSerializationTest extends TestCase { @@ -112,4 +115,31 @@ public class ClientMethodSerializationTest extends TestCase { return output; } + public void testSerializeTwice() { + String name = "javascriptFunctionName"; + String[] arguments = { "1", "2", "3" }; + JsonArray args = (JsonArray) JsonCodec.encode(arguments, null, + Object[].class, null).getEncodedValue(); + ClientConnector connector = null; + + ClientMethodInvocation original = new ClientMethodInvocation(connector, + "interfaceName", JAVASCRIPT_CALLBACK_METHOD, new Object[] { + name, args }); + + ClientMethodInvocation copy = (ClientMethodInvocation) serializeAndDeserialize(original); + assertEquals(copy.getMethodName(), original.getMethodName()); + assertEquals(copy.getParameters().length, + original.getParameters().length); + for (int i = 0; i < copy.getParameters().length; i++) { + Object originalParameter = original.getParameters()[i]; + Object copyParameter = copy.getParameters()[i]; + if (originalParameter instanceof JsonValue) { + assertEquals(((JsonValue) originalParameter).toJson(), + ((JsonValue) copyParameter).toJson()); + } else { + assertEquals(originalParameter, copyParameter); + } + } + } + } |