4

I have a jsp file and a HttpSessionListener to monitor HttpSession destroying activities.

index.jsp

<%
    HttpSession s = request.getSession();
    System.out.println("SID1 : " + s.getId());
    s.setAttribute("Key", "Value");
    s.invalidate();
%>

SessionListener

@WebListener
public class SessionListener implements HttpSessionListener {

    @Override
    public void sessionCreated(HttpSessionEvent se) {
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        HttpSession s = se.getSession();
        System.out.println("SID2 : " + s.getId());
        System.out.println(s.getAttribute("Key"));
        s.invalidate();
        System.out.println("Session Destroyed");
    }

}

Now according to the above situation, sending a HTTP request to index.jsp should create a HttpSession and call it's invalidate() method, meanwhile the HttpSessionListener should catch the same HttpSession and call the invalidate() once again, and this process should repeat over and over again.

Which should eventually result in throwing a java.lang.StackOverflowError. But I have got the the following output without any errors.

SID1 : A2751AE9E782A17380415B0078C9ED90
SID2 : A2751AE9E782A17380415B0078C9ED90
Value
Session Destroyed

I have tested it with both GlassFish and Tomcat servers, the result stays the same. Can someone explain what's going on?

Nikos Paraskevopoulos
  • 39,514
  • 12
  • 85
  • 90
Roshana Pitigala
  • 8,437
  • 8
  • 49
  • 80

1 Answers1

2

Apparently this is because session is already invalidated when you invoke invalidate method for the second time from public void sessionDestroyed(HttpSessionEvent se) {...}.

Session.beginInvalidate() returns false value in this case and this block is not invoked:

boolean result = beginInvalidate();

try {
    //if the session was not already invalid, or in process of being invalidated, do invalidate
    if (result) {
         //tell id mgr to remove session from all contexts
         _handler.getSessionIdManager().invalidateAll(_sessionData.getId());
    }
}

In particular,_handler.getSessionIdManager().invalidateAll invokes SessionHandler.invalidate, which invokes SessionHandler.removeSession which invokes _sessionListeners.get(i).sessionDestroyed(event);.

So in case if the session is already invalidated this scenario doesn't work.

Andremoniy
  • 34,031
  • 20
  • 135
  • 241
  • If the session has been invalidated already, how come the attributes get printed in the output when called in the listener? – Roshana Pitigala Feb 14 '18 at 16:53
  • 1
    I don't understand this your last question. What's the problem? First time you invoke `s.invalidate();` from the JSP. It does all this sequence described in my answer. After that your `sessionDestroyed` is invoked where all printouts are performed. Then you call there `s.invalidate()` again, but it has no effect as at this moment session is already invalidated. – Andremoniy Feb 14 '18 at 16:55