我在用Java 9的Stackwalking API进行了一些实验,发现所收集的帧少于实际stacktrace给出的帧。我想知道,是否有可能获得相同数量的框架和元素?
看看以下测试:
@Test
public void test() {
NaughtyBusiness nb = new NaughtyBusiness();
try {
//This method throws an exception
nb.callMeForGoodTime(NaughtyBusiness.AlcoholTolerance.LOW);
} catch (Exception e) {
StackTraceElement[] stackTrace = e.getStackTrace();
StackWalker stackWalker = StackWalker.getInstance(StackWalker.Option.SHOW_HIDDEN_FRAMES);
List<StackWalker.StackFrame> frames =
stackWalker.walk(stackFrameStream -> stackFrameStream.collect(toList()));
System.out.println(frames);
}
}
我现在如果调试代码,我将看到以下内容:
第一个明显的区别是StacktraceElements与StackFrames的数量(26 vs 23)。不过,更令人惊讶的是,缺失的帧(用红色标记)实际上是在相互干扰,即从我的自定义代码中,而在两者之间共享的绿色部分只是样板。
因此,问题是,如何使用StackWalking API获得“丢失”的帧?我尝试了3个选项SHOW_HIDDEN_FRAMES
,RETAIN_CLASS_REFERENCE
和SHOW_REFLECT_FRAMES
,但没有一个起作用。
StackWalker.walk方法从调用点开始构建堆栈帧。在这种情况下,您是从test()
方法中调用它的,所以它将以该方法开始构建一系列堆栈帧。
StackWalker根本不了解您捕获的异常。异常是从另一个地方抛出的,即NaughtyBusiness.playStupidGamesWinStupidPrizes方法,这就是其堆栈框架不同的原因。
要获得与异常的堆栈框架相同的StackWalker框架,您需要使用引发异常的相同方法来调用StackWalker.walk。