Java 9 StackWalker

In this tutorial, we’re gonna look at efficient way of stack walking for lazy access, filtering stack trace with Java 9 StackWalker.

I. StackWalker
1. Overview

The way we usually access the stack information before is using a Throwable to get the stack trace.

Use this old method, we have to get all available elements of entire stack. If the caller only want to get top few frames on the stack, there is no way to reduce the cost.
In addition, Throwable::getStackTrace method return an array of StackTraceElement objects, which contain class names and method names, not the actual Class instances.

Java 9 defines a stack walking API that provides laziness and frame filtering. Now we can make short walk that stops at a frame for a condition, or long walk on the entire stack.

2. StackFrame

A StackFrame object represents a method invocation returned by StackWalker.
StackFrame contains methods to get stack information:

Notice that getDeclaringClass() method will throw an UnsupportedOperationException if StackWalker is not configured with Option.RETAIN_CLASS_REFERENCE.

3. StackWalker

StackWalker object allows us to traverse and access to stacks. It contains some useful and powerful methods:

The most important method is walk() that helps:
+ open a StackFrame stream for the current thread.
+ then apply the function with that StackFrame stream.
Because it is a Java 8 Stream, we can only traverse once and it will be closed when walk() method returns.

So, if we try to use the stream after walk() method returns, it will throw a java.lang.IllegalStateException:

To get StackWalker object, we use StackWalker::getInstance method:

– If option parameter is empty, StackWalker skips all hidden frames and no class reference is retained.
If a security manager is present and input option contains Option.RETAIN_CLASS_REFERENCE, it calls its checkPermission() method for StackFramePermission("retainClassReference").

estimateDepth is the number of stack frames to be traversed.
This is an example for getting a StackWalker:

II. Example
1. Walk all StackFrames

2. Skip some StackFrames

Using java.util.stream.Stream.skip(long n) helps us to skip a number of nearest StackFrames.

3. Limit StackFrames

Using java.util.stream.Stream.limit(long maxSize) helps us to limit a number of StackFrames. The Stream after limit() method only contains up to that number of StackFrames.

Because Stream is lazy, so limit reduces the cost of the capture.

4. Filter Frames by Class

5. Get Caller Class

II. Source Code

Run code above, the results:


Related Posts


Got Something To Say:

Your email address will not be published. Required fields are marked *

*