【问题标题】:Is it ever OK to throw a java.lang.Error?抛出 java.lang.Error 可以吗?
【发布时间】:2010-04-22 13:33:08
【问题描述】:

我有一个用于 Web 应用程序的插件模块。 如果模块未正确加载,则 Web 应用程序继续运行没有意义,并且 Web 应用程序可能根本不应该加载,我们希望该模块始终正确初始化。 如果我要抛出运行时异常,它会进入日志,并被忽略,因为应用程序无论如何都会继续运行,最终用户永远不会知道...... 我知道只有在异常情况下才会抛出错误,并且它们通常与系统无法恢复的情况有关,但是在这种情况下你会怎么做?

【问题讨论】:

  • 不应该是错误,而是一些合适的子类,无论是现有的还是您定义的。但是在你的情况下抛出一个 Error 的子类是合适的。

标签: java web-applications error-handling


【解决方案1】:

我经常在业务代码中使用的唯一 ErrorExceptionInInitializerError。在 static 初始化块中你别无选择。

但是,即使您将其放入 Web 应用程序中,该 Web 应用程序仍会继续侦听 HTTP 请求。最好的办法是在 Filter 中进行模块加载或初始化,监听 /*url-pattern 并让 Filter 相应地阻止 HTTP 请求。例如

private boolean allModulesAreLoaded;

@Override
public void init(FilterConfig config) {
    try {
        // Load modules.
        allModulesAreLoaded = true;
    } catch (Exception e) {
        // Handle.
    }
}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {
    if (allModulesAreLoaded) {
        chain.doFilter(request, response);
    } else {
        throw new ServletException("Not all modules are loaded.");
    }
}

这将产生带有给定消息的 HTTP 500 错误。

【讨论】:

    【解决方案2】:

    不知道 OSGi 究竟是如何获得捆绑包的依赖管理的(=类似于插件)。在另一个捆绑包准备好之前,不会加载一个捆绑包。也许您可以使用相同的机制(或简单地使用 OSGi 本身;))等待一个插件/应用程序,直到另一个插件准备好。或者,如果应用程序无法正确找到/加载您的插件,则您在启动期间关闭该应用程序。

    【讨论】:

    • 似乎是所有钉子的锤子,但是喜欢OSGi,我倾向于赞成。此外,任何类型的依赖管理机制都应该可以工作(IoC,你的名字)。
    【解决方案3】:

    记录错误,然后使用 System.Exit 退出应用程序

    【讨论】:

    • 这没有提供关于应用程序失败原因的指示(除了返回代码之外)。
    • @HotLicks 我添加了一个建议,首先记录错误然后退出。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-09
    • 2014-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-13
    • 2014-03-10
    相关资源
    最近更新 更多