java - 如何在 init 异常时中止启动过程

标签 java servlets jakarta-ee websphere

我在 Websphere 8.5.5.8 上有一个 Web 应用程序,一个(或多或少是空的)EAR 项目,其中包含我的 WAR 项目。

在我的主 Servlet(在启动时加载)中,我会进行一些检查,看看一切是否正常。 如果不是,我将抛出 javax.servlet.ServletException

我的期望是,Websphere 会识别出存在问题并中止我的应用程序的启动,因此它根本无法使用。

实际发生的情况是,Websphere 只是以 Waring 级别记录该异常,异常甚至在另一个文件中,而不是在日志本身中:

[06.04.16 07:42:27:229 CEST] 0000004c FfdcProvider  W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC-Vorfall an C:\IBM\WAS8.5\profiles\AppSrv01\logs\ffdc\server1_bb44715_16.04.06_07.42.27.2056702894000999712166.txt com.ibm.ws.webcontainer.servlet.ServletInstance.init 259 erstellt.

然后我的应用程序无论如何都会启动,因此它可以与浏览器一起使用。当然,人们开始使用它并随后认识到存在问题。深入日志文件后发现启动失败。

问题: 我该怎么做才能使 Websphere 中止启动过程? 我可能会抛出一种特殊的异常吗? 我试过了

  • javax.servlet.ServletException
  • javax.servlet.UnavailableException
  • java.lang.Error

我找到了this在 IBM 论坛中,这表明我的预期行为将违反 JEE 规范,这对我来说没有多大意义。

我尝试了如上所述的javax.servlet.ServletContextListenerhere ,还有一个好处是,我会在日志中收到一条错误消息,但应用程序仍然启动。

如上所述here我尝试了启动 bean 。那里发布的解决方案对我不起作用,那些专有的启动 bean 是 not allowed in a WAR ,它们也是 Deprecated 。我只有一个 EAR 项目,因为 Websphere/RAD 迫使我在本地环境中使用一个。在测试/生产系统上,仅使用 WAR。

如果我使用 EJB 3.1 定义的启动 bean:

import javax.annotation.PostConstruct;
import javax.ejb.Singleton;
import javax.ejb.Startup;
@Singleton
@Startup
public class MyStartupBean {
    public boolean start() {
        System.out.println("MyStartupBean.start()");
        return false;
    }
    public void stop(){
        System.out.println("MyStartupBean.stop()");
    }
    @PostConstruct
    public void postConstruct() {
        System.out.println("MyStartupBean.postConstruct()");
    }
}

start() 方法没有被调用,我只在日志中看到 postConstruct() 消息。在 postConstruct() 中抛出异常不会中止启动过程。

最佳答案

到目前为止,我只想出了一个解决方法(受到 Jason Faust 在 https://stackoverflow.com/a/1337927/5072526 中评论的启发):

有一个静态标志,如果初始化已正确完成,则将其设置为 true。 使用过滤器检查该标志,如果为假则输出错误,因此至少应用程序在启动失败时似乎不可用:

public class HealthCheckFilter implements Filter{
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        if(AppBridge.isStartupFinished()) {
            chain.doFilter(request, response);
        }else {
            HttpServletResponse httpResponse = (HttpServletResponse) response;
            httpResponse.setCharacterEncoding(AppConstants.ENCODING);
            httpResponse.setContentType("text/plain");
            httpResponse.setStatus(500);
            PrintWriter out = httpResponse.getWriter();
            out.write("Startup failed");
        }
    }
    /* Methods init(FilterConfig filterConfig) and destroy() ommitted*/
}

关于java - 如何在 init 异常时中止启动过程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36442669/

相关文章:

java - HIbernate HQL 意外 token

java - 尽快停止/取消断开连接的 GET 请求线程

tomcat - 将样式表链接到 Servlet

java - 如何在另一个 servlet 中访问同一个 ServletContext 对象?

java - entityManager.persist 不将任何内容保存到数据库

java - 每个优秀的 Java/Java EE 开发人员都应该能够回答的问题?

java - GridPane 中的文本居中

java - 文本字段显示控制台结果

java - 使用 JAVA 和 JPA 1.0 对 DB2 进行大量更新或插入

java - 属性 hibernate.connection.driver_class 2 未指定 JDBC 驱动程序类