如何记录在Java中被finally块的异常掩盖的异常?

时间:2011-03-30 21:33:11

标签: java debugging exception finally

只是一张便条: 我知道在Java finally块中应该永远不会抛出异常,否则这是非常非常非常糟糕的做法。
知道我应该在try-catch内使用finally来处理(例如记录或忽略)所有异常并阻止它们传播。
知道 Java 7的Throwable有getSuppressed方法,但我的目标是Java 5& 6。

问题:在Java中,try-finally如果try块抛出异常(将其命名为 A ),则控件到达finally块(如果它也不例外,但在这个问题上并不有趣。然后,如果finally块抛出异常(将其命名为 B ),则异常 A 被抑制,或被屏蔽/吞噬,异常 B 传播给调用者。

问题:当一个异常被另一个异常压缩并记录/记录第一个异常时,我能以某种方式检测到这种情况吗?
......我花了太多时间来推理为什么抛出了特殊的异常并且不知道到底发生了什么。

理由:通常有问题的try-finally块在库中编码(今天它是Hibernate),所以我无法修改它们。

解决方案限制:正如我在开始时所指出的那样,可能的解决方案不应该在Java 7上进行转发,但另一方面,不需要是生产等级(这样会是一个奖励)。 AOP是一个选择。

(请不要发布琐碎的答案,例如“使用Java 7进行开发”):)

2 个答案:

答案 0 :(得分:1)

我认为问题是即使使用AOP,也无法拦截异常消费过程。使用AOP,您可以捕获所有创建的异常,但是您无法知道它们何时被消耗。

例如:

try {
    ...
} catch (Exception e) {
    log.boom("Ouchies happened here", e);
}

并非所有异常都被重新抛出。

然而,在某个级别,MOST异常ARE最终被抛出,以便调用者可以处理它们。

所以,考虑到你可能会“泄漏”异常,游戏就是试图找到“泄漏”例外。

使用AOP,您可以在创建时消除每个异常(无论您是在异常级别执行此操作,还是必须在单个级别执行此操作,我不能说 - 不熟悉AOP在在这种情况下练习。)

在创建异常时捕获异常,然后开始通过AOP包装方法调用。执行此操作时,您可以捕获方法抛出的异常。

所以,通过一点点工作,您知道从方法返回时a)创建了哪些异常并且b)抛出了哪些异常。如果从方法中遍历返回异常的“由...引起”的异常,则可以将这些异常从“此方法创建的异常”列表中删除。其余的是漏洞。

理想情况下,经过一些分析后,您将能够确定哪些不被抛出(但以其他方式处理),以及哪些实际上被您的finally块遮蔽。

它不完美,而且我肯定不会在制作中使用它(我只需要在录制内容等所有竞争条件上投入大量工作。比我想做的更多的工作对于这种调试,坦率地说)。但它可能会为您提供您正在寻找的信息,特别是在小范围的课程中谨慎使用时。

答案 1 :(得分:0)

有一个名为“ExceptionCheck()”的JNI方法,毫不奇怪,它会检查挂起的异常。您可以在本机方法的中间调用它,以查看某个先前的调用是否抛出了一个异常,它等待JNI方法在实际抛出之前返回。我想知道你是否可以从最终调用本机方法,然后尝试使用ExceptionCheck来查看是​​否存在挂起的异常,如果这样做的话。我不知道是否会这样,但我认为值得一试。