- java.lang.Object
-
- java.lang.StackWalker
-
public final class StackWalker extends Object
A stack walker.The
walkmethod opens a sequential stream ofStackFrames for the current thread and then applies the given function to walk theStackFramestream. The stream reports stack frame elements in order, from the top most frame that represents the execution point at which the stack was generated to the bottom most frame. TheStackFramestream is closed when thewalkmethod returns. If an attempt is made to reuse the closed stream,IllegalStateExceptionwill be thrown.The stack walking options of a
StackWalkerdetermines the information ofStackFrameobjects to be returned. By default, stack frames of the reflection API and implementation classes are hidden andStackFrames have the class name and method name available but not theClass reference.StackWalkeris thread-safe. Multiple threads can share a singleStackWalkerobject to traverse its own stack. A permission check is performed when aStackWalkeris created, according to the options it requests. No further permission check is done at stack walking time.- API Note:
- Examples
1. To find the first caller filtering a known list of implementation class:
StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE); Optional<Class<?>> callerClass = walker.walk(s -> s.map(StackFrame::getDeclaringClass) .filter(interestingClasses::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).collect(Collectors.toList()));nullargument to a constructor or method in thisStackWalkerclass will cause aNullPointerExceptionto be thrown. - Since:
- 9
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description static classStackWalker.OptionStack walker option to configure the stack frame information obtained by aStackWalker.static interfaceStackWalker.StackFrameAStackFrameobject represents a method invocation returned byStackWalker.
-
Method Summary
All Methods Static Methods Instance Methods Concrete Methods Modifier and Type Method Description voidforEach(Consumer<? super StackWalker.StackFrame> action)Performs the given action on each element ofStackFramestream of the current thread, traversing from the top frame of the stack, which is the method calling thisforEachmethod.Class<?>getCallerClass()Gets theClassobject of the caller who invoked the method that invokedgetCallerClass.static StackWalkergetInstance()Returns aStackWalkerinstance.static StackWalkergetInstance(StackWalker.Option option)Returns aStackWalkerinstance with the given option specifying the stack frame information it can access.static StackWalkergetInstance(Set<StackWalker.Option> options)Returns aStackWalkerinstance with the givenoptionsspecifying the stack frame information it can access.static StackWalkergetInstance(Set<StackWalker.Option> options, int estimateDepth)Returns aStackWalkerinstance with the givenoptionsspecifying the stack frame information it can access.<T> Twalk(Function<? super Stream<StackWalker.StackFrame>,? extends T> function)Applies the given function to the stream ofStackFrames for the current thread, traversing from the top frame of the stack, which is the method calling thiswalkmethod.
-
-
-
Method Detail
-
getInstance
public static StackWalker getInstance()
Returns aStackWalkerinstance.This
StackWalkeris configured to skip all hidden frames and no class reference is retained.- Returns:
- a
StackWalkerconfigured to skip all hidden frames and no class reference is retained.
-
getInstance
public static StackWalker getInstance(StackWalker.Option option)
Returns aStackWalkerinstance with the given option specifying the stack frame information it can access.If a security manager is present and the given
optionisOption.RETAIN_CLASS_REFERENCE, it calls itscheckPermissionmethod forRuntimePermission("getStackWalkerWithClassReference").- Parameters:
option-stack walking option- Returns:
- a
StackWalkerconfigured with the given option - Throws:
SecurityException- if a security manager exists and itscheckPermissionmethod denies access.
-
getInstance
public static StackWalker getInstance(Set<StackWalker.Option> options)
Returns aStackWalkerinstance with the givenoptionsspecifying the stack frame information it can access. If the givenoptionsis empty, thisStackWalkeris configured to skip all hidden frames and no class reference is retained.If a security manager is present and the given
optionscontainsOption.RETAIN_CLASS_REFERENCE, it calls itscheckPermissionmethod forRuntimePermission("getStackWalkerWithClassReference").- Parameters:
options-stack walking option- Returns:
- a
StackWalkerconfigured with the given options - Throws:
SecurityException- if a security manager exists and itscheckPermissionmethod denies access.
-
getInstance
public static StackWalker getInstance(Set<StackWalker.Option> options, int estimateDepth)
Returns aStackWalkerinstance with the givenoptionsspecifying the stack frame information it can access. If the givenoptionsis empty, thisStackWalkeris configured to skip all hidden frames and no class reference is retained.If a security manager is present and the given
optionscontainsOption.RETAIN_CLASS_REFERENCE, it calls itscheckPermissionmethod forRuntimePermission("getStackWalkerWithClassReference").The
estimateDepthspecifies the estimate number of stack frames thisStackWalkerwill traverse that theStackWalkercould use 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 <= 0SecurityException- if a security manager exists and itscheckPermissionmethod denies access.
-
walk
public <T> T walk(Function<? super Stream<StackWalker.StackFrame>,? extends T> function)
Applies the given function to the stream ofStackFrames for the current thread, traversing from the top frame of the stack, which is the method calling thiswalkmethod.The
StackFramestream will be closed when this method returns. When a closedStream<StackFrame>object is reused,IllegalStateExceptionwill be thrown.- API Note:
- For example, to find the first 10 calling frames, first skipping those frames
whose declaring class is in package
com.foo:List<StackFrame> frames = StackWalker.getInstance().walk(s -> s.dropWhile(f -> f.getClassName().startsWith("com.foo.")) .limit(10) .collect(Collectors.toList()));This method takes a
Functionaccepting aStream<StackFrame>, rather than returning aStream<StackFrame>and allowing the caller to directly manipulate the stream. The Java virtual machine is free to reorganize a thread's control stack, for example, via deoptimization. By taking aFunctionparameter, this method allows access to stack frames through a stable view of a thread's control stack.Parallel execution is effectively disabled and stream pipeline execution will only occur on the current thread.
- Implementation Note:
- The implementation stabilizes the stack by anchoring a frame
specific to the stack walking and ensures that the stack walking is
performed above the anchored frame. When the stream object is closed or
being reused,
IllegalStateExceptionwill be thrown. - Type Parameters:
T- The type of the result of applying the function to the stream of stack frame.- Parameters:
function- a function that takes a stream of stack frames and returns a result.- Returns:
- the result of applying the function to the stream of stack frame.
-
forEach
public void forEach(Consumer<? super StackWalker.StackFrame> action)
Performs the given action on each element ofStackFramestream of 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
public Class<?> getCallerClass()
Gets theClassobject of the caller who invoked the method that invokedgetCallerClass.This method filters reflection frames,
MethodHandle, and hidden frames regardless of theSHOW_REFLECT_FRAMESandSHOW_HIDDEN_FRAMESoptions thisStackWalkerhas been configured with.This method should be called when a caller frame is present. If it 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 bundle on behalf of the caller. It invokesgetCallerClassto identify the class whose method calledUtil::getResourceBundle. Then, it obtains the class loader of that class, and uses the class loader to load the resource bundle. The caller class in this example isMyTool.
An equivalent way to find the caller class using theclass Util { private final StackWalker walker = StackWalker.getInstance(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 frames not shown below):
When theOptional<Class<?>> caller = walker.walk(s -> s.map(StackFrame::getDeclaringClass) .skip(2) .findFirst());getCallerClassmethod is called from a method that is 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.
-
-