I've got a JSP problem (Tomcat 5.0.19). I use a Timer object to kick off occasional actions in my JSP engine - flushing cached information, pinging my RMI peers, etc. My timers sometimes complain about "Timer already stopped" when I try to schedule a new event. A little digging shows that this can happen when a the JVM tries to garbage collect a timer. This is absurd, my timer object is in the application scope, it should never even begin to be garbage collected! How do I make sure that the timer is always strongly reachable? I've tried using daemon and non-daemon timers, tried adding static references to the timer - nothing seems to work. Here's the code that makes the timer:
You are correct in that an object in application scope should never be garbage collected. The map implementing the attribute list in the servlet context object will retain a reference to the object. There must be some other subtle factor at play here.
Just to be 100% clear - actually, the timers are not being garbage collected, but their finalizer is being called. It is the calling of the finalizer that cancels the timers even though I am still using it. So the real question is, why is the finalizer of an application scoped object being called? And how do I stop this from happening? For now I have a workaround. I have created a class that extends timers, and uses a delegate "real" timer. When it gets an IllegalStateException thrown from the "real" timer, then I just create a new one and start giving all my scheduled tasks to that. It's an ugly solution, so I'd like something better, but for now it works.