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

时间:2009-12-01 15:37:44

标签: java tomcat servlets

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

但是,当servlet的init()方法抛出ServletException时,contextDestroyed()方法永远不会被调用 - >资源不发布 - > servlet不会被Tomcat卸载(即使它的init方法永远不会完成,它仍处于“运行”状态。)

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

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

编辑 - 我认为这是因为Tomcat Manager中显示的每个状态行代表整个战争,而不是servlet。战争可能包含几个servlet,其中一些成功启动而另一些则没有。容器启动时调用Initializer,仅在删除整个容器时调用其destroy。这导致了一个相关的问题 - 是否有类似的内置方法来监控单个servlet的状态?

(我知道我可以编写自定义代码来监视servlet,无论是通过JMX还是不通过,但这不属于 这个问题)。

3 个答案:

答案 0 :(得分:1)

在现实世界中,init()永远不会失败。如果失败,那么开发人员应该修复的是编程错误。 appserver webcontainer与它无关。 servlet将保持不可用状态。

答案 1 :(得分:1)

据我所知,没有外部请求,绝对没有办法。 ServletContextListener为您提供了正确的信号(当所有servlet都已初始化 - 成功与否时),但是您无法枚举上下文中的所有servlet来测试它们的状态,因为相关的ServletContext方法已被弃用,现在返回一个空的枚举器。

简而言之,唯一的方法是使用非标准API;特别是,使用Tomcat的JMX API来实现这一点几乎是微不足道的,这是我推荐的课程。

答案 2 :(得分:0)

你在运行什么容器?

Tomcat例如支持JMX。你总是可以编写自己的JMX-bean。