Skip to content

Commit

Permalink
fix: return immidiately if VaadinSession is not initialized (#11974)
Browse files Browse the repository at this point in the history
fixes #11961
  • Loading branch information
Denis committed Oct 6, 2021
1 parent 44cefaf commit 809539c
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 10 deletions.
52 changes: 42 additions & 10 deletions flow-server/src/main/java/com/vaadin/flow/server/VaadinSession.java
Original file line number Diff line number Diff line change
Expand Up @@ -174,16 +174,27 @@ public void valueBound(HttpSessionBindingEvent arg0) {
*/
@Override
public void valueUnbound(HttpSessionBindingEvent event) {
// The Vaadin session instance may be not yet initialized properly via
// {@link #refreshTransients(WrappedSession, VaadinService)}. It happens
// when the session is deserialized and container decides that it's
// expired. Such session is not known to anyone (except deserializer)
// and nothins should be done with it: just return immediately.
//
// Be aware that not initialized session doesn't have the
// correct/expected state: it has no lock, service, session, etc.
if (!isInitialized()) {
getLogger().warn(
"A VaadinSession instance not associated to any service is getting unbound. "
+ "Session destroy events will not be fired and UIs in the session will not get detached. "
+ "This might happen if a session is deserialized but never used before it expires.");
return;
}
// If we are going to be unbound from the session, the session must be
// closing
// Notify the service
if (service == null) {
getLogger()
.warn("A VaadinSession instance not associated to any service is getting unbound. "
+ "Session destroy events will not be fired and UIs in the session will not get detached. "
+ "This might happen if a session is deserialized but never used before it expires.");
} else if (VaadinService.getCurrentRequest() != null
&& getCurrent() == this) {
if (VaadinService.getCurrentRequest() != null &&

getCurrent() == this) {
checkHasLock();
// Ignore if the session is being moved to a different backing
// session or if GAEVaadinServlet is doing its normal cleanup.
Expand Down Expand Up @@ -232,7 +243,8 @@ public WebBrowser getBrowser() {
/**
* Set the web browser associated with this session.
*
* @param browser the web browser object
* @param browser
* the web browser object
*/
public void setBrowser(WebBrowser browser) {
checkHasLock();
Expand Down Expand Up @@ -622,8 +634,10 @@ public void removeUI(UI ui) {
* <code>Lock</code> interface than {@link Lock#lock()} and
* {@link Lock#unlock()}.
*
* @return the <code>Lock</code> that is used for synchronization, never
* <code>null</code>
* @return the <code>Lock</code> that is used for synchronization, it's
* never <code>null</code> for the session which is in use, i.e. if
* {@link #refreshTransients(WrappedSession, VaadinService)} has
* been called for it
* @see #lock()
* @see Lock
*/
Expand Down Expand Up @@ -1085,4 +1099,22 @@ public StreamResourceRegistry getResourceRegistry() {
public String getCsrfToken() {
return csrfToken;
}

/**
* Checks whether the session is properly initialized/in use.
* <p>
* The session is initialized if
* {@link #refreshTransients(WrappedSession, VaadinService)} has been called
* for it. If the session is just created or deserialized but not yet in
* real use then it's not initialized and it's state is incomplete.
*
* @return whether the session is initialized
*/
private boolean isInitialized() {
boolean isInitialized = service != null;
assert isInitialized
|| session == null : "The wrapped session must be null if the service is null (which happens after deserialization)";
return isInitialized;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -498,4 +498,24 @@ protected Lock getSessionLock(WrappedSession wrappedSession) {
Assert.assertNull(vaadinSession.getSession());
}

@Test
public void valueUnbound_sessionIsNotInitialized_noAnyInteractions() {
VaadinSession session = Mockito.spy(TestVaadinSession.class);

HttpSessionBindingEvent event = Mockito
.mock(HttpSessionBindingEvent.class);
session.valueUnbound(null);

Mockito.verify(session).valueUnbound(null);
Mockito.verifyNoInteractions(event);
Mockito.verifyNoMoreInteractions(session);
}

public static class TestVaadinSession extends VaadinSession {

public TestVaadinSession() {
super(null);
}
}

}

0 comments on commit 809539c

Please sign in to comment.