code: @Override
      public void doSessionClosedListeners() {
          runManagementTask(new Runnable() {
              @Override
              public void run() {
                  try {
                      // The particular management listeners change on strategy, so get them here.
                      for (final SessionManagementListener listener : getManagementListeners()) {
                          listener.doSessionClosed(SessionManagementBeanImpl.this);
                      }
  
                      // XXX should there be a markChanged() here because the session status is now closed?
                      // Or is that covered by the fact we generate a session-closed message?
                  } catch (Exception ex) {
                      logger.warn("Error during doSessionClosed session listener notifications:", ex);
                  }
              }
          });
      }
docs: Notify the management listeners on a filterWrite.
  <p/>
  NOTE: this starts on the IO thread, but runs a task OFF the thread.