-
Bug
-
Resolution: Unresolved
-
Normal
-
None
-
6.5.7
-
None
-
None
-
None
I have developed a service that receives heartbeats via js from the browser. The purpose is to detect when the user has closed the tab (which cannot be detected reliably via events) and to invalidate the session and release locks in such cases.
This required implementing a javax.servlet.Filter which basically reimplements the servlet session.timeout. In this filter I get the HttpSession and set a session attribute. I do this by wrapping the request into a custom class:
private static class SessionAccessUpdatingRequest extends HttpServletRequestWrapper { SessionAccessUpdatingRequest(HttpServletRequest request) { super(request); } @Override public HttpSession getSession() { return getSession(true); } @Override public HttpSession getSession(boolean create) { HttpSession session = super.getSession(create); if ( session != null ) { session.setAttribute(LAST_ACCESSED_TIME, System.currentTimeMillis()); } return session; } }
This service is not aware of ZK and this is how it is supposed to be. Now I run into the situation that setting a session attribute in a SessionListener triggers the above mentioned HttpSessionListener23 which in turn creates new sessions by calling getSession(true) on the request which causes a loop and hence a stack overflow:
at com.tn_ag.ws.heartbeat.HeartbeatTimer.init(HeartbeatTimer.java:70) at com.tn_ag.ws.heartbeat.SessionListener.sessionCreated(SessionListener.java:42) at org.mortbay.jetty.servlet.AbstractSessionManager.addSession(AbstractSessionManager.java:575) at org.mortbay.jetty.servlet.AbstractSessionManager.newHttpSession(AbstractSessionManager.java:413) at org.mortbay.jetty.Request.getSession(Request.java:1243) at javax.servlet.http.HttpServletRequestWrapper.getSession(HttpServletRequestWrapper.java:227) at com.tn_ag.ws.heartbeat.SessionInvalidationFilter$SessionAccessUpdatingRequest.getSession(SessionInvalidationFilter.java:114) at org.zkoss.zk.ui.http.WebManager.getSession(WebManager.java:426) at org.zkoss.zk.ui.http.SessionResolverImpl.getSession(SessionResolverImpl.java:37) at org.zkoss.zk.ui.Sessions.getCurrent(Sessions.java:57) at org.zkoss.zk.ui.Sessions.getCurrent(Sessions.java:45) at org.zkoss.zk.ui.http.HttpSessionListener23.attributeAdded(HttpSessionListener23.java:55) at org.mortbay.jetty.servlet.AbstractSessionManager$Session.setAttribute(AbstractSessionManager.java:1073) at com.tn_ag.ws.heartbeat.HeartbeatTimer.init(HeartbeatTimer.java:70) at com.tn_ag.ws.heartbeat.SessionListener.sessionCreated(SessionListener.java:42) at org.mortbay.jetty.servlet.AbstractSessionManager.addSession(AbstractSessionManager.java:575)
I can break this cycle by changing the custom request class such that it is aware that getSession(true) was already called. However, I think it is not correct that the listener for setting attributes tries to create a new session because it should be the case that a session exists when an attribute is set for the session.
- relates to
-
ZK-2291 ZK gets into an infinte loop when HTTP session attributes are changed inside of sessionCreated()
-
- Closed
-