我有一个实现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还是不通过,但这不属于 这个问题)。
答案 0 :(得分:1)
在现实世界中,init()
永远不会失败。如果失败,那么开发人员应该修复的是编程错误。 appserver webcontainer与它无关。 servlet将保持不可用状态。
答案 1 :(得分:1)
据我所知,没有外部请求,绝对没有办法。 ServletContextListener为您提供了正确的信号(当所有servlet都已初始化 - 成功与否时),但是您无法枚举上下文中的所有servlet来测试它们的状态,因为相关的ServletContext方法已被弃用,现在返回一个空的枚举器。
简而言之,唯一的方法是使用非标准API;特别是,使用Tomcat的JMX API来实现这一点几乎是微不足道的,这是我推荐的课程。
答案 2 :(得分:0)
你在运行什么容器?
Tomcat例如支持JMX。你总是可以编写自己的JMX-bean。