如何使ServletContextListener停止Java EE应用程序?

时间:2011-07-11 22:11:22

标签: servlets java-ee servlet-listeners

我有一个ServletContextListener,它在我的Java EE应用程序启动时执行一些数据库管理功能。这在JPA和应用程序的其他部分启动/加载之前在我的应用程序中运行。如果数据库维护失败,我将记录错误。如果数据库维护失败,应用程序将无法正常运行,我想暂停应用程序。

如何从ServletContextListener.contextInitialized中优雅正确地停止应用程序?

以下Viven给出的解决方案很接近,但并不完全。当我抛出RuntimeException时,Glassfish处于不一致的状态,其管理控制台无法访问,但某些进程仍在运行并保持端口3700(IIOP?)打开,从而阻止重启。

2 个答案:

答案 0 :(得分:5)

如果您的ServletContextListener引发异常,则无法正确加载该网络应用,并且应用服务器可能会阻止所有后续请求(并回复500错误)。

它并没有完全阻止应用程序启动,也没有停止应用程序,但它阻止了应用程序的任何进一步使用,并且可能对您的情况有用。

在规范中进行适当验证后,此行为在规范中不是必需的。服务器可能(不是必须)返回500错误。因此,必须谨慎使用此解决方案。

请参阅this Answer以获取Servlet规范中的引用。

答案 1 :(得分:5)

在侦听器中,捕获任何异常并使用servlet上下文属性来存储有关错误的标志或其他有用信息。您可能还应该记录一些内容以指示该应用程序无法正常运行。

此时,您的选项可能取决于您应用的体系结构。如果所有请求都由单个控制器/调度程序servlet处理,则使用init方法检查上下文属性并抛出UnavailableException可能是有意义的。请注意,该异常仅适用于抛出它的特定servlet。如果您的应用程序包含许多servlet或允许直接访问其他资源,这使得该方法不易管理。

另一种选择是创建一个拦截每个请求的过滤器,检查上下文属性然后抛出异常。其他变化肯定是可能的。