Java EE应用程序启动失败

14

在Java EE应用程序初始化期间发生未处理异常时,是否有防止应用程序启动的方法?我基本上正在寻找一种方式,使应用程序进入“j2ee.state.failed”状态(根据JSR-77),在从ServletContextListenerSingletonStartup bean中抛出未处理异常的情况下。

EJB规范似乎表明,如果在初始化Singleton bean期间发生异常,则应用程序将继续启动和运行而不会出现错误;但是,只有bean本身可能处于无法调用的状态。不幸的是,这不是我想要的行为。

4.8.4 Singleton Error Handling(单例错误处理)

在Singleton初始化过程中发生的错误被视为致命错误,并必须导致Singleton实例的丢弃。可能的初始化错误包括注入失败、从PostConstruct方法抛出的系统异常,或容器管理事务的PostConstruct方法无法成功提交。如果单例未能初始化,则对单例尝试的调用将导致根据第3.4.3节和第3.4.4节定义的异常。

Servlet规范在要求方面比较含糊,似乎没有“要求”容器以任何特定的方式运行,但仅仅是通过使用“可能”这个词(suggesting)来表明Web模块应该继续启动,但任何请求都应该导致内部服务器错误。不幸的是,这并不是我所期望的行为。如果无法处理任何请求,为什么Web应用程序仍然应该继续启动并且看起来正在运行呢?

11.6 Listener Exceptions

容器可以对Web应用程序的所有后续请求作出HTTP状态码500的响应,以指示应用程序错误。

根据我的经验,我发现应用服务器会以不同的方式处理这种要求。有些容器实际上会阻止应用程序在这些情况下启动,而其他容器则仅仅抑制异常并以500错误响应请求,如规范中建议的那样。

我是否忽视了规范中任何防止初始化期间发生异常时阻止应用程序启动的部分?


+1;好问题。这也是我的经验 - 他们做得不一样... - home
3个回答

2
我认为这取决于您使用的应用服务器。正如您所提到的,如何处理无效状态的部署是由他来决定的。当它们失败时,这些部署并不活跃,因此您必须提供一个服务来查找提示,这些提示应在成功启动时提供给您的部署。如果没有这些提示,则可以通知管理员。但这都是特定于服务器或需要外部工具的。
在一些项目中,我们使用[nagios][1]和[rhq][2]来检查部署情况。例如,nagios会检查JBossAS上的jmx控制台以获取所需的部署信息。当部署后的应用程序在几秒钟内未显示时,IT人员会收到通知。

Tomcat 7.x将不会启动一个从ServletContextListener.contextInitialized()抛出未检查异常的应用程序,而WebLogic 12.1.3将会启动该应用程序。 - javabrett

1
+1 给梗答案。也许我的经验可以帮到你:如果在 @PostConstruct 方法中将 bean 与注释 @Startup 和 @Singleton 结合使用会抛出异常,这将阻止整个应用程序(ear)在 JBoss AS 7.1.1 上启动。

2
同样适用于WebSphere Application Server 8.0+。 - Brett Kail

0
在网页应用程序的情况下,为什么不创建一个Servlet过滤器,检查你自己的“失败”标志,并且如果该标志被激活,则返回500给任何请求呢?从容器的角度来看,你的应用程序当然会启动。

目标是防止应用程序在无效状态下启动。ServletContainerListeners和Singleton Startup beans通常用于执行应用程序所需的初始化;如果在此初始化过程中发生错误,则理想状态是快速失败。这可以防止用户检测到故障,立即引起管理员的注意。它还允许应用程序不可知的部署工具普遍检测应用程序启动失败并相应地行为;例如,回滚应用程序更新。 - shelley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接