summaryrefslogtreecommitdiffstats
path: root/server
diff options
context:
space:
mode:
authorArtur Signell <artur@vaadin.com>2015-10-09 23:44:47 +0300
committerVaadin Code Review <review@vaadin.com>2015-11-12 10:54:33 +0000
commitf3eb1b4383848e28447717502083439d9e0dc0b7 (patch)
treebb81ac60f1b98ef3ea5121a62908b60a14ba4318 /server
parent142f7dcebb249c9c458cdbade014212b1a9ac27d (diff)
downloadvaadin-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.java9
-rw-r--r--server/tests/src/com/vaadin/tests/server/ClientMethodSerializationTest.java30
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);
+ }
+ }
+ }
+
}