Class StackWalker
Thewalk method opens a sequential streamofStackFrames for the current thread and then appliesthe given function to walk theStackFrame stream.The stream reports stack frame elements in order, from the top most framethat represents the execution point at which the stack was generated tothe bottom most frame.TheStackFrame stream is closed when thewalk method returns.If an attempt is made to reuse the closed stream,IllegalStateException will be thrown.
Stack walker options configure the stack frameinformation obtained by aStackWalker.By default, the class name and method information are collected butnot theClass reference.The method information can be dropped via theDROP_METHOD_INFO option. TheClass object can be retained foraccess via theRETAIN_CLASS_REFERENCE option.Stack frames of the reflection API and implementation classes arehidden by default.
StackWalker is thread-safe. Multiple threads can sharea singleStackWalker object to traverse its own stack.
- API Note:
- Examples
1. To find the first caller filtering out a known list of implementation class:
StackWalker walker = StackWalker.getInstance(Set.of(Option.DROP_METHOD_INFO, Option.RETAIN_CLASS_REFERENCE)); Optional<Class<?>> callerClass = walker.walk(s -> s.map(StackFrame::getDeclaringClass) .filter(Predicate.not(implClasses::contains)) .findFirst());2. To snapshot the top 10 stack frames of the current thread,
Unless otherwise noted, passing aList<StackFrame> stack = StackWalker.getInstance().walk(s -> s.limit(10).toList());nullargument to aconstructor or method in thisStackWalkerclasswill cause aNullPointerExceptionto be thrown. - Since:
- 9
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionstatic enumStack walker option to configure thestack frameinformation obtained by aStackWalker.static interfaceAStackFrameobject represents a method invocation returned byStackWalker.Method Summary
Modifier and TypeMethodDescriptionvoidforEach(Consumer<? superStackWalker.StackFrame> action) Performs the given action on each element ofStackFramestreamof the current thread, traversing from the top frame of the stack,which is the method calling thisforEachmethod.Class<?> Gets theClassobject of the caller who invoked the methodthat invokedgetCallerClass.staticStackWalkerReturns aStackWalkerinstance.staticStackWalkergetInstance(StackWalker.Option option) Returns aStackWalkerinstance with the given option specifyingthe stack frame information it can access.staticStackWalkergetInstance(Set<StackWalker.Option> options) Returns aStackWalkerinstance with the givenoptionsspecifyingthe stack frame information it can access.staticStackWalkergetInstance(Set<StackWalker.Option> options, int estimateDepth) Returns aStackWalkerinstance with the givenoptionsspecifyingthe stack frame information it can access.<T> Twalk(Function<? superStream<StackWalker.StackFrame>, ? extends T> function) Applies the given function to the stream ofStackFramesfor the current thread, traversing from the top frame of the stack,which is the method calling thiswalkmethod.
Method Details
getInstance
Returns aStackWalkerinstance.This
StackWalkeris configured to skip allhidden frames andnoclass reference is retained.- Returns:
- a
StackWalkerconfigured to skip allhidden frames andnoclass reference is retained.
getInstance
Returns aStackWalkerinstance with the given option specifyingthe stack frame information it can access.- Parameters:
option-stack walking option- Returns:
- a
StackWalkerconfigured with the given option
getInstance
Returns aStackWalkerinstance with the givenoptionsspecifyingthe stack frame information it can access.If the given
optionsis empty, thisStackWalkerisconfigured to skip allhidden framesand noclass reference is retained.- Parameters:
options-stack walking options- Returns:
- a
StackWalkerconfigured with the given options
getInstance
Returns aStackWalkerinstance with the givenoptionsspecifyingthe stack frame information it can access.If the given
optionsis empty, thisStackWalkerisconfigured to skip allhidden framesand noclass reference is retained.The
estimateDepthspecifies the estimate number of stack framesthisStackWalkerwill traverse that theStackWalkercoulduse as a hint for the buffer size.- Parameters:
options-stack walking optionsestimateDepth- Estimate number of stack frames to be traversed.- Returns:
- a
StackWalkerconfigured with the given options - Throws:
IllegalArgumentException- ifestimateDepth <= 0
walk
Applies the given function to the stream ofStackFramesfor the current thread, traversing from the top frame of the stack,which is the method calling thiswalkmethod.The
StackFramestream will be closed whenthis method returns. When a closedStream<StackFrame>objectis reused,IllegalStateExceptionwill be thrown.- API Note:
- For example, to find the first 10 calling frames, first skipping those frameswhose declaring class is in package
com.foo:List<StackFrame> frames = StackWalker.getInstance().walk(s -> s.dropWhile(f -> f.getClassName().startsWith("com.foo.")) .limit(10) .toList());This method takes a
Functionaccepting aStream<StackFrame>,rather than returning aStream<StackFrame>and allowing thecaller to directly manipulate the stream. The Java virtual machine isfree to reorganize a thread's control stack, for example, viadeoptimization. By taking aFunctionparameter, this methodallows access to stack frames through a stable view of a thread's controlstack.Parallel execution is effectively disabled and stream pipelineexecution will only occur on the current thread.
- Implementation Note:
- The implementation stabilizes the stack by anchoring a framespecific to the stack walking and ensures that the stack walking isperformed above the anchored frame. When the stream object is closed orbeing reused,
IllegalStateExceptionwill be thrown. - Type Parameters:
T- The type of the result of applying the function to the stream ofstack frame.- Parameters:
function- a function that takes a stream ofstack frames and returns a result.- Returns:
- the result of applying the function to the stream ofstack frame.
forEach
Performs the given action on each element ofStackFramestreamof the current thread, traversing from the top frame of the stack,which is the method calling thisforEachmethod.This method is equivalent to calling
walk(s -> { s.forEach(action); return null; });- Parameters:
action- an action to be performed on eachStackFrameof the stack of the current thread
getCallerClass
Gets theClassobject of the caller who invoked the methodthat invokedgetCallerClass.This method filtersreflectionframes,
MethodHandle, andhidden frames regardless of theSHOW_REFLECT_FRAMESandSHOW_HIDDEN_FRAMESoptionsthisStackWalkerhas been configured with.This method should be called when a caller frame is present. Ifit is called from the bottom most frame on the stack,
IllegalCallerExceptionwill be thrown.This method throws
UnsupportedOperationExceptionif thisStackWalkeris not configured with theRETAIN_CLASS_REFERENCEoption.- API Note:
- For example,
Util::getResourceBundleloads a resource bundleon behalf of the caller. It invokesgetCallerClassto identifythe class whose method calledUtil::getResourceBundle.Then, it obtains the class loader of that class, and usesthe class loader to load the resource bundle. The caller classin this example isMyTool.An equivalent way to find the caller class using theclass Util { private final StackWalker walker = StackWalker.getInstance(Set.of(Option.DROP_METHOD_INFO, Option.RETAIN_CLASS_REFERENCE)); public ResourceBundle getResourceBundle(String bundleName) { Class<?> caller = walker.getCallerClass(); return ResourceBundle.getBundle(bundleName, Locale.getDefault(), caller.getClassLoader()); }}class MyTool { private final Util util = new Util(); private void init() { ResourceBundle rb = util.getResourceBundle("mybundle"); }}walkmethod is as follows(filtering the reflection frames,MethodHandleand hidden framesnot shown below):When theOptional<Class<?>> caller = walker.walk(s -> s.map(StackFrame::getDeclaringClass) .skip(2) .findFirst());getCallerClassmethod is called from a method thatis the bottom most frame on the stack,for example,static public void mainmethod launched by thejavalauncher, or a method invoked from a JNI attached thread,IllegalCallerExceptionis thrown. - Returns:
Classobject of the caller's caller invoking this method.- Throws:
UnsupportedOperationException- if thisStackWalkeris not configured withOption.RETAIN_CLASS_REFERENCE.IllegalCallerException- if there is no caller frame, i.e. when thisgetCallerClassmethod is called from a method which is the last frame on the stack.