Stack-walking API
To debug exceptions, we look at the root cause of exception by traversing the stack trace. Prior to Java 9, we all used Thread.getStackTrace() to get StackTraceElement objects in the form of arrays.
StackTraceElement: Each element of StackTraceElement is a single StackFrame, which provides details about classname, method name, filename, and line number where the exception was generated. Except for the first StackFrame, all the other elements represent the method invocation call from the starting point of the application to the point where the exception generated. This is helpful when we want auditing of generated error logs.
Java 9 StackWalker API provides several features such as filtering, asserting, and skipping certain classes in the stack trace. We can get either a full stack trace or short stack trace for a current thread at any point.
StackWalker provides various methods for capturing information about stacks, such as:
- forEach: For the current thread it returns each StackFrame stream to perform actions
- getInstance(): This returns the current instance of StackWalker
- walk(): This is used to open a sequential stream for each StackFrame for the current thread, where we can apply functions such as limit, skip, and filter
List<StackFrame> stack = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).walk((s) -> s.collect(Collectors.toList()));
The preceding snippet gives a list of all the StackFrame of the current thread by retaining class references. In the following snippet, we needed only the first 10 frames in the method and the skip frames, which are declared in the com.packt.java9dependency package:
List<StackFrame> frames = StackWalker.getInstance().walk(s -> s.dropWhile(f -> f.getClassName().startsWith("com.packt.java9dependency")).limit(10).collect(Collectors.toList()));