【问题标题】:Access to an Exception caught by the caller of a method访问方法调用者捕获的异常
【发布时间】:2025-10-06 03:40:01
【问题描述】:

我们有第三方 java 库;在其中没有正确处理异常。

如下所示:

public class UserClass {

    public static void main(String[] args) {

        try {
          // Do something and a exception gets thrown
        } catch (Exception e) {
          StupidLogger.debug("Exception Occured"); // Here as the exception is not logged we don't know what has actually happened.
        }

    }
}

由于我无法访问UserClass 的代码,我无法更改里面的代码。

我可以访问StupidLogger 类代码。那么,是否可以通过堆栈跟踪或使用Runtime 类或通过StupidLogger 类的debug() 方法中的任何其他方式访问Exception 对象并正确记录它。

【问题讨论】:

  • 如果被抓住了,那就没了。
  • 您为什么要访问Exception?只记录一条消息可能是正确的做法。如果第三方代码在遇到异常时没有进行适当的清理,那将是您应该向其开发人员提出的错误。还是要打印堆栈跟踪?这并不总是合适的;见*.com/questions/7361201/…
  • “如果它被抓住了,它就消失了。”。不必要。对Exception 对象的引用可能位于main 堆栈帧中的局部变量中...取决于JIT 编译器是否已优化掉该变量。
  • @StephenC 不过,一旦catch 块完成执行,声明(以及范围)就完成了。您可以保留引用或将其传递给在 不同 范围内持续存在的另一个变量,但一旦它被捕获,它仍然会消失。
  • @Unihedron - 但是当您调用 debug 时,e 仍在范围内(在 main 内),这就是 OP 想要访问它的时候。 main(如所写)中的处理程序中没有任何内容访问 e 的事实并没有超出范围。

标签: java exception logging


【解决方案1】:

那么,是否可以通过堆栈跟踪访问异常对象

没有。

或使用运行时类

没有

或通过 StupidLogger 类的 debug() 方法中的任何其他方式

没有。

没有 JVM 字节码,也没有反射方法允许方法查看当前方法调用以外的方法调用的堆栈帧。

我认为唯一的可能是深入研究本机代码,然后开始对父堆栈帧的地址感到不满。您甚至可能需要求助于从(例如)JNI 或 JNA 方法调用 本机汇编代码,才能做到这一点!


不要去那里。正确的解决方案是更改StupidLogger 的API 并显式传递异常引用。如果不能,请向供应商投诉……或向提供您因设计不佳而无法调试的软件的人投诉。


实际上,如果main中的局部变量e没有被使用,那么JIT编译器可能会将其优化掉。这意味着试图从本机代码中找到它可能是徒劳的。

【讨论】:

    【解决方案2】:

    我猜 StupidLogger 中还有其他方法可以调试,其中一种(可能是错误)接受 Throwable。如果没有,你可以创建自己的 Logger 类来扩展 StupidLogger,并创建方法 debug(String msg, Throwable T),对 T 做任何你想做的事情,然后调用 debug(msg)。

    【讨论】:

    • "由于我无权访问 UserClass 的代码,我无法更改其中的代码。" 这不适用于 OP。