为何在HttpSessionListener中调用invalidate()不会引发StackOverflowError?
invalidate() in HttpSessionListener Doesn't Trigger a StackOverflowError? Great question—this seems like a classic "why isn't the infinite loop happening?" scenario, and the answer boils down to how servlet containers handle session destruction under the hood.
Let's recap your setup to make sure we're on the same page:
- You've got an
index.jspthat creates anHttpSessionand immediately callsinvalidate()on it. - You've registered an
HttpSessionListenerthat listens for session destruction events, and in itssessionDestroyed()method, you callinvalidate()on the session again.
Logically, this looks like it should spiral into an infinite loop: calling invalidate() triggers the listener, which calls invalidate() again, which triggers the listener, and so on until the stack overflows. But as you noticed, this doesn't happen. Here's why:
Servlet containers (like Tomcat, Jetty, etc.) include a built-in guard against exactly this scenario. When you first call invalidate() on a session, the container marks the session with an internal state flag—something like "in the process of being destroyed".
When your listener's sessionDestroyed() method runs and tries to call invalidate() again, the container first checks the session's state. If it sees the session is already being destroyed, it skips all the destruction logic entirely: no re-triggering of the sessionDestroyed() event, no additional cleanup steps, just an immediate return.
For example, in Tomcat's StandardSession implementation, there's an isValid() method that checks if the session is still active. When invalidate() is called, it first sets the session's validity to false before firing the destruction event. Any subsequent calls to invalidate() will first check isValid(); if it's already false, the method exits right away without doing anything else.
This is a deliberate safeguard in servlet container implementations to prevent accidental infinite loops caused by listeners interacting with session destruction logic. The servlet spec doesn't explicitly spell this out, but it's a common, sensible implementation choice across all major containers.
内容的提问来源于stack exchange,提问作者Roshana Pitigala

