2009-12-01 38 views
3

我有一个Initializer类实现ServletContextListener接口。在其contextInitialized()方法中,我初始化了一些必须销毁的全局类,否则无法卸载该servlet。如果init()失败,清理servlet后

然而,当servlet的init()方法抛出ServletException,该contextDestroyed()方法不会被调用 - >资源没有被释放 - > servlet没有得到由Tomcat的卸载(它仍然在“运行”状态,即使其init方法从未完成)。

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

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

编辑 - 我认为这是因为Tomcat管理器中显示的每个状态行代表整个战争,而不是一个servlet。一场战争可能包含多个servlet,其中一些成功启动,另一些则不成功。在容器启动时调用Initializer,并且仅当整个容器被丢弃时才调用它的销毁。这导致了一个相关的问题 - 是否有类似的内置方法来监视单个servlet的状态? (我知道我可以通过JMX编写自定义代码来监视servlet,但这不在 这个问题的范围之内)。

回答

1

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

总之,唯一的方法就是通过非标准的API;尤其是使用Tomcat的JMX API来做到这一点几乎是微不足道的,这是我推荐的课程。

+0

根据[ServletContextListener]的javadoc(http://tomcat.apache.org/tomcat-7.0-doc/servletapi/javax/servlet/ServletContextListener。html)中,contextInitialized方法是在“Web应用程序中的任何过滤器或servlet被初始化之前”驱动的,这与方法名称中过去式可能导致您相信的内容相反。 – 2013-06-18 10:06:54

1

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

+0

这是一个配置/部署错误,而不是编程错误。那我该如何监控servlet的状态呢? – ripper234 2009-12-01 16:01:53

+0

配置错误仍然是您的责任。监控可以通过阅读日志来完成。 – BalusC 2009-12-01 16:03:58

+0

我看不出这是如何相关的。我们的操作人员监控的部分是容器状态。我们认为它代表了_servlet_状态,但是它表明它没有。剩下的唯一问题是Tomcat是否应该在容器中的所有servlet都无法启动时停止容器。 – ripper234 2009-12-01 16:06:11

0

你在运行什么容器?

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

+0

Tomcat,正如我在问题中所述。我知道我可以编写自定义(JMX或不)代码来监视这个问题,但这不在这个问题的范围之内 - 我想知道是否有现成的解决方案。 – ripper234 2009-12-01 16:13:48