【问题标题】:How to record exceptions masked by finally block's exceptions in Java?如何在Java中记录被finally块的异常掩盖的异常?
【发布时间】:2011-03-30 21:33:10
【问题描述】:

只是一个注释: 我知道在 Java 中 finally 块永远不应该抛出异常,否则这是 [非常、非常、非常] 不好的做法。
知道我应该在finally 中使用try-catch 来处理(例如记录或忽略)所有异常并防止它们传播。
知道 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 进行开发”之类的琐碎答案:)

【问题讨论】:

    标签: java debugging exception finally


    【解决方案1】:

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

    例如:

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

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

    但是,在某个级别,大多数异常最终都会被抛出,以便调用者可以处理它们。

    因此,考虑到无论如何您都可能“泄漏”异常,游戏将尝试找到“泄漏”异常。

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

    一旦您在创建异常时捕获它们,您就可以开始通过 AOP 包装方法调用。执行此操作时,您可以捕获该方法引发的异常。

    因此,通过一些工作,您就知道从方法返回时 a) 创建了哪些异常,以及抛出了哪些异常。如果您从方法中遍历返回的异常的“由”树的异常,则可以将这些从“此方法创建的异常”列表中抛出。其余的是泄漏。

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

    它是不完美的,而且我肯定不会在生产中使用它(我只需要在围绕录制内容等的所有竞争条件下投入大量工作。比我想做的工作还多对于这种调试,坦率地说)。但它可能会为您提供您正在寻找的信息,尤其是在少量类域中谨慎使用时。

    【讨论】:

    • 如果我拦截每一个方法,这会使JVM运行缓慢吗?我注意到有时 Eclipse 的断点会使 JVM 减慢 50 倍(JVM 1.6,不错的 Eclipse 版本)...
    • 显然拦截会产生一些成本,但它不应该削弱系统。但这是谨慎使用它的另一个原因,并且仅用于调试。您不必在每个方法上都有它,只需在要跟踪异常的每个入口点上都有它。
    【解决方案2】:

    有一个名为“ExceptionCheck()”的 JNI 方法,毫不奇怪,它会检查待处理的异常。您可以在本机方法的中间调用它,以查看某个先前的调用是否引发了异常,该异常正在等待 JNI 方法在实际引发之前返回。我想知道您是否可以从 finally 调用本机方法,然后尝试使用 ExceptionCheck 来查看是否有待处理的异常,如果可以的话。我不知道它是否会,但我会说它值得一试。

    【讨论】:

    • 我无法修改finally。它们被密封在 jar 文件中。而且有很多:)
    猜你喜欢
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 2016-09-19
    • 1970-01-01
    • 2017-05-05
    • 2014-01-08
    • 1970-01-01
    相关资源
    最近更新 更多