2009-12-01 76 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