vaadin / multiplatform-runtime

4 stars 1 forks source link

IllegalStateException can occur when MPR removes session attribute #93

Closed TatuLund closed 3 years ago

TatuLund commented 3 years ago

Please take a look at following trace:

Caused by: java.lang.IllegalStateException: removeAttribute: Session already invalidated at org.apache.catalina.session.StandardSession.removeAttribute(StandardSession.java:1315) at org.apache.catalina.session.StandardSession.removeAttribute(StandardSession.java:1289) at org.apache.catalina.session.StandardSessionFacade.removeAttribute(StandardSessionFacade.java:153) at com.vaadin.flow.server.WrappedHttpSession.removeAttribute(WrappedHttpSession.java:126) at com.vaadin.mpr.core.AbstractLegacyWrapper.handleDetach(AbstractLegacyWrapper.java:167) at com.vaadin.flow.component.ComponentEventBus.fireEventForListener(ComponentEventBus.java:205) at com.vaadin.flow.component.ComponentEventBus.fireEvent(ComponentEventBus.java:194) at com.vaadin.flow.component.Component.fireEvent(Component.java:358) at com.vaadin.flow.component.ComponentUtil.fireEvent(ComponentUtil.java:386) at com.vaadin.flow.component.ComponentUtil.onComponentDetach(ComponentUtil.java:264) at java.base/java.util.Optional.ifPresent(Optional.java:183)

We have several detach listeners. This stacktrace shows the notification of the MPR addon. Unfortunately, we have the case that we close the Vaadin UI programmatically, which closes the UI but not the session.

Anytime, when the application container closes the session, all detach listeners are getting notified. MPR tries to remove an attribute which will be rejected with an excpetion because it seems that the session is already in closing state. But this exception aborts the notification of all remaining listeners that do important clean up stuff in our application.

Question: Why doesn't MPR addon catch that exception? And: Does it makes sense to abort detach listeners notification if anyone of them fails?

PAX523 commented 3 years ago

Tomcat has a special check in their session implementation: org.apache.catalina.session.StandardSession.removeAttribute(String, boolean)

       if (!this.isValidInternal()) {
          throw new IllegalStateException(sm.getString("standardSession.removeAttribute.ise"));

       }
       ...
    protected boolean isValidInternal() {
       return this.isValid || this.expiring;
    }

And Jetty always accepts all attribute removals, independently of the state of the session: org.eclipse.jetty.server.session.Session.setAttribute(String, Object)