Java 如果init()失败,请在servlet之后清理

Java 如果init()失败,请在servlet之后清理,java,tomcat,servlets,Java,Tomcat,Servlets,我有一个初始化器类,它实现了ServletContextListener接口。在其contextInitialized()方法中,我初始化了一些必须销毁的全局类,否则无法卸载servlet 但是,当servlet的init()方法抛出ServletException时,contextDestroyed()方法从未被调用-->资源未释放-->servlet不会被Tomcat卸载(即使其init方法从未完成,它仍保持“运行”状态) 我的问题是-在这种情况下如何清理资源 好处:为什么servlet甚至

我有一个
初始化器
类,它实现了
ServletContextListener
接口。在其
contextInitialized()
方法中,我初始化了一些必须销毁的全局类,否则无法卸载servlet

但是,当servlet的
init()
方法抛出
ServletException
时,
contextDestroyed()
方法从未被调用-->资源未释放-->servlet不会被Tomcat卸载(即使其
init
方法从未完成,它仍保持“运行”状态)

我的问题是-在这种情况下如何清理资源

好处:为什么servlet甚至会进入“运行”状态?我从中了解到,除非
init()
方法成功完成,否则它不应该运行

编辑-我认为这是因为Tomcat Manager中显示的每一个状态行都代表一场完整的战争,而不是一个servlet。一场战争可能包含多个servlet,其中一些成功启动,另一些未启动。当容器启动时调用
初始值设定项
,仅当整个容器被丢弃时才调用其destroy。这就引出了一个相关的问题——是否有类似的内置方法来监视单个servlet的状态

(我知道我可以编写自定义代码来监视servlet,可以通过JMX,也可以不通过JMX,但这超出了本文的范围。)
在现实世界中,
init()
应该永远不会失败。如果失败了,那么开发人员应该修复编程错误。appserver webcontainer与此无关。servlet将保持不可用。

您正在运行哪个容器


例如,Tomcat确实支持。您可以随时编写自己的JMX bean。

据我所知,如果没有外部请求,绝对无法做到这一点。ServletContextListener为您提供了正确的信号(无论是否成功初始化所有servlet),但您无法枚举上下文中的所有servlet以测试其状态,因为相关的ServletContext方法已弃用,现在返回空枚举器


简而言之,实现这一点的唯一方法是通过非标准API;特别是,使用Tomcat的JMXAPI执行此操作几乎是微不足道的,这是我推荐的课程。

这是一个配置/部署错误,而不是编程错误。那么我如何监控servlet的状态呢?配置错误仍然是您的责任。监视可以通过读取日志来完成。我看不出这有什么关系。我们的运营人员监控的一部分是集装箱状态。我们认为它代表servlet状态,但显然不是。剩下的唯一问题是,如果容器中的所有servlet都无法启动,Tomcat是否应该停止容器。我知道我可以编写自定义(JMX或不)代码来监控这一点,但这超出了这个问题的范围-我想知道是否有现成的解决方案。根据的javadoc,contextInitialized方法是“在初始化web应用程序中的任何过滤器或servlet之前”驱动的,与方法名称中的过去时可能让您相信的相反。