I would like to expire all my sessions in Tomcat. We test our product under Fitnesse and some sessions remain and the end of the session causes dependency between the tests.
I'm assuming your applications are really independent contexts. I have done something similar to what you are asking using an HttpSessionListener
for every context. The tricky part here is that you need to have a Session Collection that is loaded by the root class loader as opposed to the context class loader. This is how I remember it:
Create a class which holds the active sessions for each context. This class must reside in the tomcat /lib directory so that it becomes accessible by every context. It can't be part of any of the contexts.
public class SessionMap {
private static Map> map =
new HashMap>();
private SessionMap() {
}
public static Map> getInstance() {
return map;
}
public static void invalidate(String[] contexts) {
synchronized (map) {
List l = Arrays.asList(contexts);
for (Map.Entry> e : map.entrySet()) {
// context name without the leading slash
String c = e.getKey().getContextPath().substring(1);
if (l.contains(c)) {
for (HttpSession s : e.getValue())
s.invalidate();
}
}
}
}
}
Create a listener for every context.
public class ApplicationContextListener implements HttpSessionListener {
public void sessionCreated(HttpSessionEvent event) {
ConcurrentMap> instance = SessionMap.getInstance();
synchronized (instance) {
ServletContext c = event.getSession().getServletContext();
Set set = instance.get(c);
if (c == null) {
set = new HashSet();
instance.put(c, set);
}
set.add(event.getSession());
}
}
public void sessionDestroyed(HttpSessionEvent event) {
ConcurrentMap> instance = SessionMap.getInstance();
synchronized (map) {
ServletContext c = event.getSession().getServletContext();
Set set = instance.get(c);
if (c != null) {
set.remove(event.getSession());
}
}
}
}
Registered each listener in the corresponding context's web.xml
.
ApplicationContextListener
You can then call the following line to invalidate everything from any context.
SessionMap.invalidate();
I'm synchronizing on the map just to be on the safe side.