diff options
author | Leif Åstrand <leif@vaadin.com> | 2015-10-26 15:44:44 +0000 |
---|---|---|
committer | Vaadin Code Review <review@vaadin.com> | 2015-11-25 09:21:51 +0000 |
commit | 082851e5479a19df17084598944b45b53b38fd73 (patch) | |
tree | ed9a2a78d2454ac9f1df1796647b59f004d1862b | |
parent | 5f43e12492e565b6e29e50966ecbd380119718eb (diff) | |
download | vaadin-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.java | 9 | ||||
-rw-r--r-- | server/tests/src/com/vaadin/server/VaadinSessionTest.java | 99 |
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(); + } } |