Java:全局异常处理程序

42

Java 中有没有一种方法可以创建一个全局的异常处理器?我希望可以这样使用:

"When an exception is thrown somewhere in the WHOLE program, exit."
处理程序可能无法捕获在try-catch块中抛出的异常。
马尔廷
6个回答

62

4
以下是使用Logback处理所有未捕获异常的示例:

这是一个示例,使用Logback来处理所有未捕获的异常:

Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
    public void uncaughtException(Thread t, Throwable e) {
        LoggerFactory.getLogger("CustomLogger").error("Uncaught Exception in thread '" + t.getName() + "'", e);
        System.exit(1);
    }
});

您还可以使用Thread.setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler)方法对每个线程进行单独设置。


4

2

为了澄清,对于独立的Java应用程序或确信线程有明确定义入口点的情况,请使用setDefaultUncaughtExceptionHandler。

对于没有明确定义入口点的情况,例如在Web服务器、应用服务器上下文或其他框架中运行时,设置和拆卸由代码之外的处理程序处理,请查看该框架如何处理全局异常。通常,这些框架具有自己已建立的全局异常处理程序,您成为其中的参与者,而不是定义。

有关更详细的讨论,请参见http://metatations.com/2011/11/20/global-exception-handling-in-java/


1

DefaultUncaughtExceptionHandler是正确的答案。 几天前,Jeff Storeythis地点向我透露了这一点。 正如您所怀疑的那样,“手动”捕获的异常永远不会被此处理程序捕获。 但是我收到了以下警告:

**- 为了符合J2EE标准,Web应用程序不应使用任何线程。**

当我使用PMD插件和Eclipse IDE检查我的项目是否符合最佳实践和推荐的Java编码风格时,出现了上述警告。


- 为了符合 J2EE 规范,Web 应用程序不应使用任何线程。 - 我不知道这个。您的意思是 servlet 中的 service()(以及 doGet()、doPost() 等方法)不应该创建新线程吗? - Kolibri
我不知道那是什么意思,因为我的应用程序不是基于Web的。我已经谷歌搜索了一段时间,但没有找到任何答案,我很害怕。除了像“变量名太短”或“变量名太长”的警告之外,我发现PMD是一个很好的灵感来源。我强烈推荐使用它。 - hypercube
2
我做了一些调查,显然你不能直接在J2EE中创建线程。我找到了一些链接:http://www.theserverside.com/discussions/thread.tss?thread_id=44353和https://dev59.com/J3RB5IYBdhLWcg3wuZfo - Kolibri
谢谢,@Kolibri。 - hypercube
1
没有严肃的网络应用程序只运行在一个线程上。"一个webapp不应该使用任何线程"意味着你不应该自己创建新的线程,因为应用程序无法控制它们。使用预配置的线程池是完全可以的。 - Abhijit Sarkar

0

Threads.setDefaultUncaughtExceptionHandler() 可以使用,但并非所有情况都适用。例如,在创建 Swing 小部件之前,我在 main() 中使用它,并且它可以在由 Swing 创建的线程(例如 AWT 事件线程或 SwingWorker 线程)中工作。

不幸的是,当使用 LDAP URL 时,javax.naming.spi.NamingManager.getInitialContext() 创建的线程没有任何效果,使用 JavaSE 1.6。毫无疑问还有其他例外情况。


为什么不为新创建的线程使用 setUncaughtExceptionHandler - wonsuc
@wonsuc - 我将删除这个答案,因为它不是一个答案。我会在上面添加一条评论。如果您的评论没有得到回应,您可能需要在其他地方添加它。(我的原因是,7年后我不知道!但也许很难找到由NamingManagerGetInitialContext()创建的线程。或者我当时不知道它。) - Jeff Learman

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