Index: core/src/com/icesoft/faces/webapp/http/servlet/SessionDispatcher.java =================================================================== --- core/src/com/icesoft/faces/webapp/http/servlet/SessionDispatcher.java (revision 57) +++ core/src/com/icesoft/faces/webapp/http/servlet/SessionDispatcher.java (working copy) @@ -29,6 +29,7 @@ public abstract class SessionDispatcher extends EnvironmentAdaptingServlet { private final static Log Log = LogFactory.getLog(SessionDispatcher.class); //ICE-3073 - manage sessions with this structure + private final static MonitorFactory MONITOR_FACTORY = new MonitorFactory(); private final static Map SessionMonitors = new HashMap(); private final static CurrentServer CurrentSessionBoundServer = new CurrentServer(); private final Map sessionBoundServers = new HashMap(); @@ -82,7 +83,7 @@ final Monitor monitor; synchronized (SessionMonitors) { if (!SessionMonitors.containsKey(id)) { - monitor = new Monitor(session); + monitor = MONITOR_FACTORY.createMonitor(session); SessionMonitors.put(id, monitor); } else { monitor = (Monitor) SessionMonitors.get(id); @@ -264,6 +265,25 @@ return (SessionDispatcher) applicationMap.get(SessionDispatcher.class.getName()); } + private static class MonitorFactory { + private final static String GLASSFISH_SERVER_INFO = "Sun GlassFish Enterprise Server"; + private final static String GLASSFISH_2_1_SERVER_INFO = "Sun GlassFish Enterprise Server v2.1"; + + private Monitor createMonitor(HttpSession session) { + Monitor returnValue = null; + + String serverInfo = session.getServletContext().getServerInfo(); + if ((GLASSFISH_2_1_SERVER_INFO.equals(serverInfo)) + || (serverInfo.contains(GLASSFISH_SERVER_INFO))) { + returnValue = new GlassfishMonitor(session); + } else { + returnValue = new Monitor(session); + } + + return returnValue; + } + } + public static class Monitor { private final String POSITIVE_SESSION_TIMEOUT = "positive_session_timeout"; private Set contexts = new HashSet(); @@ -288,27 +308,44 @@ long elapsedInterval = System.currentTimeMillis() - lastAccess; try { int maxInterval = session.getMaxInactiveInterval(); - // 4496 return true if session is already expired - Object o = session.getAttribute(POSITIVE_SESSION_TIMEOUT); - - // Try to reset the max session timeout if it is -1 from a Failover on Tomcat... - // But if it was originally negative, it should stay that way. - if (maxInterval > 0) { - if (o == null) { - session.setAttribute(POSITIVE_SESSION_TIMEOUT, new Integer(maxInterval)); - } + if (maintainPositiveSessionTimeout()) { + maxInterval = updatePositiveSessionTimeout(maxInterval); + } + if (maxInterval < 1) { + return false; } else { - if (o != null) { - maxInterval = ((Integer) o).intValue(); - session.setMaxInactiveInterval(maxInterval); - } + return elapsedInterval + 15000 > maxInterval * 1000; } - return elapsedInterval + 15000 > maxInterval * 1000; } catch (Exception e) { return true; } } + protected boolean maintainPositiveSessionTimeout() { + return true; + } + + private int updatePositiveSessionTimeout(int maxInterval) { + int returnValue = maxInterval; + // 4496 return true if session is already expired + Object o = session.getAttribute(POSITIVE_SESSION_TIMEOUT); + + // Try to reset the max session timeout if it is -1 from a Failover on Tomcat... + // But if it was originally negative, it should stay that way. + if (maxInterval > 0) { + if (o == null) { + session.setAttribute(POSITIVE_SESSION_TIMEOUT, new Integer(maxInterval)); + } + } else { + if (o != null) { + returnValue = ((Integer) o).intValue(); + session.setMaxInactiveInterval(returnValue); + } + } + + return returnValue; + } + public void shutdown() { //notify all the contexts associated to this monitored session Iterator i = contexts.iterator(); @@ -334,6 +371,17 @@ } } + public static class GlassfishMonitor extends Monitor { + private GlassfishMonitor(HttpSession session) { + super(session); + } + + protected boolean maintainPositiveSessionTimeout() { + return false; + } + + } + private static class CurrentServer extends ThreadLocal { public Server lookup() { return (Server) get();