summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeif Åstrand <leif@vaadin.com>2015-10-26 15:44:44 +0000
committerVaadin Code Review <review@vaadin.com>2015-11-25 09:21:51 +0000
commit082851e5479a19df17084598944b45b53b38fd73 (patch)
treeed9a2a78d2454ac9f1df1796647b59f004d1862b
parent5f43e12492e565b6e29e50966ecbd380119718eb (diff)
downloadvaadin-framework-082851e5479a19df17084598944b45b53b38fd73.tar.gz
vaadin-framework-082851e5479a19df17084598944b45b53b38fd73.zip
Set session as current while deserializing (#9953)
Change-Id: Ib420f99c621b7d508659907615a7e8a1ae47b4d9
-rw-r--r--server/src/com/vaadin/server/VaadinSession.java9
-rw-r--r--server/tests/src/com/vaadin/server/VaadinSessionTest.java99
2 files changed, 90 insertions, 18 deletions
diff --git a/server/src/com/vaadin/server/VaadinSession.java b/server/src/com/vaadin/server/VaadinSession.java
index ab24694964..bcc07acb99 100644
--- a/server/src/com/vaadin/server/VaadinSession.java
+++ b/server/src/com/vaadin/server/VaadinSession.java
@@ -1410,8 +1410,13 @@ public class VaadinSession implements HttpSessionBindingListener, Serializable {
*/
private void readObject(ObjectInputStream stream) throws IOException,
ClassNotFoundException {
- stream.defaultReadObject();
- pendingAccessQueue = new ConcurrentLinkedQueue<FutureAccess>();
+ Map<Class<?>, CurrentInstance> old = CurrentInstance.setCurrent(this);
+ try {
+ stream.defaultReadObject();
+ pendingAccessQueue = new ConcurrentLinkedQueue<FutureAccess>();
+ } finally {
+ CurrentInstance.restoreInstances(old);
+ }
}
/**
diff --git a/server/tests/src/com/vaadin/server/VaadinSessionTest.java b/server/tests/src/com/vaadin/server/VaadinSessionTest.java
index 4944d37856..0e50abecff 100644
--- a/server/tests/src/com/vaadin/server/VaadinSessionTest.java
+++ b/server/tests/src/com/vaadin/server/VaadinSessionTest.java
@@ -15,6 +15,11 @@
*/
package com.vaadin.server;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.locks.Lock;
@@ -33,6 +38,7 @@ import org.junit.Test;
import com.vaadin.server.ClientConnector.DetachEvent;
import com.vaadin.server.ClientConnector.DetachListener;
import com.vaadin.server.communication.UIInitHandler;
+import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.util.CurrentInstance;
@@ -95,22 +101,7 @@ public class VaadinSessionTest {
session = new VaadinSession(mockService);
mockService.storeSession(session, mockWrappedSession);
- ui = new UI() {
- Page page = new Page(this, getState(false).pageState) {
- @Override
- public void init(VaadinRequest request) {
- }
- };
-
- @Override
- protected void init(VaadinRequest request) {
- }
-
- @Override
- public Page getPage() {
- return page;
- }
- };
+ ui = new MockPageUI();
vaadinRequest = new VaadinServletRequest(
EasyMock.createMock(HttpServletRequest.class), mockService) {
@Override
@@ -249,4 +240,80 @@ public class VaadinSessionTest {
+ "method for closing session", 1,
vaadinSession.getCloseCount());
}
+
+ // Can't define as an anonymous class since it would have a reference to
+ // VaadinSessionTest.this which isn't serializable
+ private static class MockPageUI extends UI {
+ Page page = new Page(this, getState(false).pageState) {
+ @Override
+ public void init(VaadinRequest request) {
+ }
+ };
+
+ @Override
+ protected void init(VaadinRequest request) {
+ }
+
+ @Override
+ public Page getPage() {
+ return page;
+ }
+ }
+
+ private static class SerializationTestLabel extends Label {
+ private transient VaadinSession session = VaadinSession.getCurrent();
+
+ private void readObject(ObjectInputStream in) throws IOException,
+ ClassNotFoundException {
+ in.defaultReadObject();
+ session = VaadinSession.getCurrent();
+ }
+ }
+
+ @Test
+ public void threadLocalsWhenDeserializing() throws Exception {
+ VaadinSession.setCurrent(session);
+ session.lock();
+ SerializationTestLabel label = new SerializationTestLabel();
+ Assert.assertEquals("Session should be set when instance is created",
+ session, label.session);
+
+ ui.setContent(label);
+ int uiId = ui.getUIId();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream out = new ObjectOutputStream(bos);
+ out.writeObject(session);
+ out.close();
+
+ session.unlock();
+
+ CurrentInstance.clearAll();
+
+ ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(
+ bos.toByteArray()));
+
+ VaadinSession deserializedSession = (VaadinSession) in.readObject();
+
+ Assert.assertNull(
+ "Current session shouldn't leak from deserialisation",
+ VaadinSession.getCurrent());
+
+ Assert.assertNotSame("Should get a new session", session,
+ deserializedSession);
+
+ // Restore http session and service instance so the session can be
+ // locked
+ deserializedSession.refreshTransients(mockWrappedSession, mockService);
+ deserializedSession.lock();
+
+ UI deserializedUi = deserializedSession.getUIById(uiId);
+ SerializationTestLabel deserializedLabel = (SerializationTestLabel) deserializedUi
+ .getContent();
+
+ Assert.assertEquals(
+ "Current session should be available in SerializationTestLabel.readObject",
+ deserializedSession, deserializedLabel.session);
+ deserializedSession.unlock();
+ }
}