Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 你如何阻止春天吞咽异常?_Java_Spring_Tomcat_Exception - Fatal编程技术网

Java 你如何阻止春天吞咽异常?

Java 你如何阻止春天吞咽异常?,java,spring,tomcat,exception,Java,Spring,Tomcat,Exception,当服务器端出现故障时,因为数据库和应用程序不同步,而不是出现错误,应用程序崩溃,spring/tomcat似乎吞下了异常并假装什么也没有发生 说我疯了,但如果程序灾难性地失败,我希望它真的灾难性地失败!是否有任何方法可以关闭这种行为?当服务器假装一切正常时,它只是在日志中抛出,这真的减慢了开发速度 如果这不是spring/tomcat的默认值,那么还有什么可能导致它呢? 不幸的是,我们正在使用大量的库和框架。斯普林通常是个嫌疑犯,但也可能是别的什么 更新 这是一个sql server数据库,我们

当服务器端出现故障时,因为数据库和应用程序不同步,而不是出现错误,应用程序崩溃,spring/tomcat似乎吞下了异常并假装什么也没有发生

说我疯了,但如果程序灾难性地失败,我希望它真的灾难性地失败!是否有任何方法可以关闭这种行为?当服务器假装一切正常时,它只是在日志中抛出,这真的减慢了开发速度

如果这不是spring/tomcat的默认值,那么还有什么可能导致它呢? 不幸的是,我们正在使用大量的库和框架。斯普林通常是个嫌疑犯,但也可能是别的什么

更新

这是一个sql server数据库,我们正在使用
SqlServerDataSource
连接该数据库。Hibernate在项目的某些部分中使用,但用于在登录时查询数据库。在客户端,我们使用extjs,还使用ExtDirectSpring为客户端的对话方法添加注释。要转换通过线路传输的数据,有Jackson,然后由extdirect json处理程序包装

有一些AOP的东西与记录异常有关,但是删除这些代码会导致相同的行为

进一步更新


好吧,让你的服务器崩溃不是个好主意!请参阅下面我的答案,了解我建议的中间立场。

如果您确实想这样做(但我认为您不应该…),您可以使用一个过滤器,一旦应用程序释放未捕获的异常,它将阻止应用程序。可能是这样的:

public class CrashFilter implements Filter {
    private boolean crashed = false;
    private String msg = "Major problem : application stopped";

    @Override
    public void doFilter(ServletRequest sr, ServletResponse sr1, FilterChain fc) throws IOException, ServletException {
        if (crashed) {
            HttpServletResponse resp = (HttpServletResponse) sr1;
            resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, msg);
            return;
        }
        try {
            fc.doFilter(sr, sr1);
        }
        catch (Exception ex) {
            crashed = true;
            throw new ServletException(ex);
        }
    }
    // init and destroy omitted from brevity
}

好的,所以我最终做到了。我基本上使用了上面的想法,但认为有足够的额外内容来发布我自己的答案

事实证明,你真的不应该像其他人建议的那样做,我在底部加了一点说明原因

这是我的过滤器:

public class FailOnErrorFilter implements Filter
{
    @Override
    public void init(FilterConfig config) throws ServletException
    {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException
    {
        try {
            filterChain.doFilter(request, response);
        }
        catch (Exception exception) {
            System.exit(1);
        }
    }

    @Override
    public void destroy()
    {

    }
}
要使其正常工作,您必须修改web.xml:

<filter>
    <filter-name>failingFilter</filter-name>
    <filter-class>fullyQualified.FailOnErrorFilter</filter-class>
    <async-supported>true</async-supported>
</filter>

<filter-mapping>
    <filter-name>failingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
顾名思义,extdirectspring使用spring,因此它的依赖性对于调用代码来说并不明显,但是如果你去挖掘(它在github上)。您将在RouterController中看到它在catch中调用以下方法

private Object handleException(MethodInfo methodInfo, BaseResponse response, Exception e, HttpServletRequest request) {
    return configurationService.getRouterExceptionHandler().handleException(methodInfo, response, e, request);
}
其中路由器控制器执行以下操作:

@Autowired(required = false)
private RouterExceptionHandler routerExceptionHandler;

public RouterExceptionHandler getRouterExceptionHandler() {
    return routerExceptionHandler;
}
如果您不提供,它将设置默认值

更新-为什么不应该这样做

事实证明,您确实不应该在tomcat应用程序中调用
System.exit
。它不仅会关闭应用程序,还会导致服务器退出。这也会导致其他正在运行的应用程序停止运行

由于其他一些原因,这也不合适:

  • 如果一系列测试中的第一个抛出异常,那么所有后续测试都将失败
  • 重新启动服务器非常耗时,您必须是破坏服务器的人才能看到异常
  • 如果您在单独的机器上运行手动测试部署,那么如果某个地方出现问题,您必须重新启动服务器
同样地:

  • 在生产过程中,它会使每个人的应用程序停机,大多数用户无法重新启动服务器
我在做什么

错误已经写入tomcat日志+数据库

  • 在调试中,我们现在还将重定向到带有stacktrace的错误页面
  • 在生产中,我们将直接重定向到“出错”页面。我们还将设置一个电子邮件服务,通知我们异常情况
  • 对于UI/selenium测试,其工作原理与调试相同
  • 对于headless Js测试,服务器拒绝后续请求,直到下一个测试重置服务器的错误状态

为了让事情变得更复杂,毫不奇怪,原来的webapp太脆弱,无法掩盖错误,因此我保留了旧的错误抑制功能,因为我们目前没有积极开发/修复它。

你知道存在异常,还是只知道没有异常传播?如果是后者,则问题可能出现在数据库访问层(例如Hibernate或其他JPA提供程序)中,因为该层中定义的bean容忍并忽略额外的数据库列,并可能最终删除更新中的任何额外列。如果是前者,我只想说“不要使用Spring”,但这可能说起来容易做起来难。举一个灾难性失败的例子,它不会发出任何错误或警告。我非常怀疑Spring应该为此负责。什么样的数据库?给我们更多的上下文细节。你真的认为如果web应用程序释放了一个未捕获的异常,tomcat(因为Spring与此无关)应该崩溃吗???如果它真的这样做了,它将不会像实际那样被使用…@warrendew肯定会有例外。Hibernate正在项目的某些部分使用,但没有用于新的内容。感谢您的回复。上面例子中的resp是什么?它不能在我的机器上编译-我已经尝试了sr和sr1,但似乎都没有sendError方法。@JonnyLeeds:对不起,我忘了一行。。。后期编辑。您还应该在一行
((HttpServletResponse)sr1)中编写它您知道您可以随时记录发生的致命错误。
并调用。。。但这样做的任何理由都是值得怀疑的(加上开发人员的理智)。只要检查Servlet规范,就有一种更好的标准方法来关闭web应用程序->抛出。
@Autowired(required = false)
private RouterExceptionHandler routerExceptionHandler;

public RouterExceptionHandler getRouterExceptionHandler() {
    return routerExceptionHandler;
}