Clean up after servlet if init() failed
I have an Initializer
class that implements the ServletContextListener
interface. In its contextInitialized()
method, I initialize some global classes that have to be destroyed, otherwise the servlet cannot be unloaded.
However, when the servlet's init()
method throws a ServletException
, the contextDestroyed()
method never gets called --> resources are not release --> servlet does not get unloaded by Tomcat (it remains in "running" state even though its init
method never finished).
My question is this - how do I cleanup the resources in this case?
Bonus: why does the servlet even get to "running" state? I understand from the documentation that it's not supposed to be running unless the init()
method finishes successfully.
Edit - I think this is because each status line displayed in Tomcat Manager represents an entire war, and not a servlet. A war may contain several servlets, with some succeeding to start and others not. The Initializer
is called when the container starts, and its destroy is called only when the entire container is dropped. This leads to开发者_JAVA百科 a related question - is there a similar built-in way to monitor the state of individual servlets?
(I'm aware I can write custom code to monitor the servlet, either via JMX, or not, but that's out of the scope of this question).
As far as I can tell there's absolutely no way to do so without an external request. ServletContextListener gives you the correct signal (when all servlets have been initialized - successfully or not), but you can't enumerate all servlets in the context to test their status because the relevant ServletContext methods were deprecated and now return an empty enumerator.
In short, the only way to do this is via a nonstandard API; in particular, it's almost trivial to do this with Tomcat's JMX API, which is the course I'd recommend.
In real world the init()
should never fail. If it fails, then it is a programming error which the developer is supposed to fix. The appserver webcontainer has nothing to do with it. The servlet will simply be kept unavailable.
What container are you running?
Tomcat for example does support JMX. You can always write your own JMX-beans.
精彩评论