Managing resource closure in a servlet container
I'm using Tomcat as a servlet container, and have many WARs deployed. Many of the WARs share common base classes, which are replicated in each context due to the different classloaders, etc.
How can I ensure resource cleanup on context destruction, without hooking each and every web.xml file to add context listeners?
Ideally, I'd like something along the lines of
class MyResourceHolder implements SomeListenerInterface {
private SomeResource resource;
{
SomeContextThingie.registerDestructionListener(this);
}
public void onDestroy() { resource.close(); }
}
I could put something in each web.xml, but since there are potentially many WARs and only ones that actually initialize the resource need to clean it up, it seems more natural to register for cleanup when the resource is initialized rather than duplicating a lot of XML configuration and then maybe cleaning up.
(In this particular case, I'm initiating an orderly shutdown of a SQL connection pool. But I see this being useful in many other situations as well...)
I'm sure there's some blisteringly obvious solution ou开发者_Python百科t there, but my Google-fu is failing me right now. Thanks!
There's no other feasible option than ServletContextListener
.
If you're already on Servlet 3.0, then you could just annotate it with @WebListener
, ship it with the webapp and it will be automagically loaded. But with Servlet 2.5 and older you really need to hassle with the web.xml
.
You could put the resources in a shared-classloader and make them available as JNDI resources - you'd have to be very careful to keep your apps in sync by doing that though - though it's an option.
Might depend on what kind of resources you're cleaning, and what kind of churn you expect to see in your API.
Note: Classloader issues can be very difficult to debug - "Class XClass is not an instance of XClass" can drive you nuts.
Edit1: Another options: you could use finalizers on your pool or other object - this should allow you to execute code (say when a webapp is unloaded and the pool is recycled) - this is how many JDK classes clean up native resources. If you do this though, be very careful as deadlocking on the finalizer queue will block all kinds of important cleanup, and likely crash your JVM, since nothing which uses finalizers will get gc'd.
Move your SQL Connection pool out of the web application and into the web container, and access it through JNDI.
精彩评论