The Tomcat backgroundprocess for expiring sessions does not wait for the servlet context (application loaded by a filter) to be fully initialized. The following stacktrace happens while Filter.init is still being executed (hence the application is only partly initialized and shouldn't receive any work): at org.apache.wicket.protocol.http.WebApplication.sessionUnbound(WebApplication.java:552) at org.apache.wicket.session.HttpSessionStore$SessionBindingListener.valueUnbound(HttpSessionStore.java:465) at org.apache.catalina.session.StandardSession.removeAttributeInternal(StandardSession.java:1800) at org.apache.catalina.session.StandardSession.expire(StandardSession.java:865) at org.apache.catalina.session.StandardSession.isValid(StandardSession.java:658) at org.apache.catalina.session.ManagerBase.processExpires(ManagerBase.java:534) at org.apache.catalina.session.ManagerBase.backgroundProcess(ManagerBase.java:519) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.java:1352) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1530) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.processChildren(ContainerBase.java:1540) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run(ContainerBase.java:1519) at java.lang.Thread.run(Thread.java:722)
Configuring an application in a Filter.init() method is a poor design choice. Application initialization should happen in a ServletContextListener. There is a little ambiguity in section 6.2.1 of the Servlet specification but your interpretation (that Filter#init() must be called for all filters before requests are served) is consistent with how the Tomcat developers have implemented filter initialization. That said, I do not see how the behavior you describe can occur. The background processing method exits immediately if the component is not available - which it isn't when the Filters are being started. I have moved the starting/stopping of the thread since the thread can't do anything until the start method completes so there is no point starting it earlier. However, that shouldn't change the current behavior. I also found and fixed a problem in Tomcat trunk where the test for component availability was being skipped. However, Tomcat 7 does not exhibit that problem. Marking this as fixed due to the Tomcat 8 fix.