StackWalker (Java SE 9 & JDK 9 ) (original) (raw)
- java.lang.StackWalker
public final class StackWalker
extends Object
A stack walker.
The walk method opens a sequential stream of StackFrames for the current thread and then applies the given function to walk the StackFrame
stream. 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. The StackFrame
stream is closed when the walk
method returns. If an attempt is made to reuse the closed stream,IllegalStateException
will be thrown.
The stack walking options of aStackWalker
determines the information ofStackFrame objects to be returned. By default, stack frames of the reflection API and implementation classes are hidden and StackFrame
s have the class name and method name available but not the Class reference.StackWalker
is thread-safe. Multiple threads can share a single StackWalker
object to traverse its own stack. A permission check is performed when a StackWalker
is 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,
List<StackFrame> stack = StackWalker.getInstance().walk(s ->
s.limit(10).collect(Collectors.toList()));
Unless otherwise noted, passing a null
argument to a constructor or method in this StackWalker
class will cause a NullPointerException to be thrown.
Since:
9
Nested Class Summary
Nested Classes
Modifier and Type Class Description static class StackWalker.Option Stack walker option to configure the stack frame information obtained by a StackWalker. static interface StackWalker.StackFrame A StackFrame object represents a method invocation returned byStackWalker. Method Summary
All Methods Static Methods Instance Methods Concrete Methods
Modifier and Type Method Description void forEach(Consumer<? super StackWalker.StackFrame> action) Performs the given action on each element of StackFrame stream of the current thread, traversing from the top frame of the stack, which is the method calling this forEach method. Class<?> getCallerClass() Gets the Class object of the caller who invoked the method that invoked getCallerClass. static StackWalker getInstance() Returns a StackWalker instance. static StackWalker getInstance(StackWalker.Option option) Returns a StackWalker instance with the given option specifying the stack frame information it can access. static StackWalker getInstance(Set<StackWalker.Option> options) Returns a StackWalker instance with the given options specifying the stack frame information it can access. static StackWalker getInstance(Set<StackWalker.Option> options, int estimateDepth) Returns a StackWalker instance with the given options specifying the stack frame information it can access. T walk(Function<? super Stream<StackWalker.StackFrame>,? extends T> function) Applies the given function to the stream of StackFrames for the current thread, traversing from the top frame of the stack, which is the method calling this walk method. * ### Methods inherited from class java.lang.[Object](../../java/lang/Object.html "class in java.lang") `[clone](../../java/lang/Object.html#clone--), [equals](../../java/lang/Object.html#equals-java.lang.Object-), [finalize](../../java/lang/Object.html#finalize--), [getClass](../../java/lang/Object.html#getClass--), [hashCode](../../java/lang/Object.html#hashCode--), [notify](../../java/lang/Object.html#notify--), [notifyAll](../../java/lang/Object.html#notifyAll--), [toString](../../java/lang/Object.html#toString--), [wait](../../java/lang/Object.html#wait--), [wait](../../java/lang/Object.html#wait-long-), [wait](../../java/lang/Object.html#wait-long-int-)`
Method Detail
* #### getInstance public static [StackWalker](../../java/lang/StackWalker.html "class in java.lang") getInstance() Returns: a `StackWalker` configured to skip all[hidden frames](../../java/lang/StackWalker.Option.html#SHOW%5FHIDDEN%5FFRAMES) and no [class reference](../../java/lang/StackWalker.Option.html#RETAIN%5FCLASS%5FREFERENCE) is retained. * #### getInstance public static [StackWalker](../../java/lang/StackWalker.html "class in java.lang") getInstance([StackWalker.Option](../../java/lang/StackWalker.Option.html "enum in java.lang") option) Returns a `StackWalker` instance with the given option specifying the stack frame information it can access. If a security manager is present and the given `option` is[Option.RETAIN\_CLASS\_REFERENCE](../../java/lang/StackWalker.Option.html#RETAIN%5FCLASS%5FREFERENCE), it calls its [checkPermission](../../java/lang/SecurityManager.html#checkPermission-java.security.Permission-) method for `RuntimePermission("getStackWalkerWithClassReference")`. Parameters: `option` \- [stack walking option](../../java/lang/StackWalker.Option.html "enum in java.lang") Returns: a `StackWalker` configured with the given option Throws: `[SecurityException](../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager exists and its`checkPermission` method denies access. * #### getInstance public static [StackWalker](../../java/lang/StackWalker.html "class in java.lang") getInstance([Set](../../java/util/Set.html "interface in java.util")<[StackWalker.Option](../../java/lang/StackWalker.Option.html "enum in java.lang")> options) Returns a `StackWalker` instance with the given `options` specifying the stack frame information it can access. If the given `options` is empty, this `StackWalker` is configured to skip all[hidden frames](../../java/lang/StackWalker.Option.html#SHOW%5FHIDDEN%5FFRAMES) and no[class reference](../../java/lang/StackWalker.Option.html#RETAIN%5FCLASS%5FREFERENCE) is retained. If a security manager is present and the given `options` contains[Option.RETAIN\_CLASS\_REFERENCE](../../java/lang/StackWalker.Option.html#RETAIN%5FCLASS%5FREFERENCE), it calls its [checkPermission](../../java/lang/SecurityManager.html#checkPermission-java.security.Permission-) method for `RuntimePermission("getStackWalkerWithClassReference")`. Parameters: `options` \- [stack walking option](../../java/lang/StackWalker.Option.html "enum in java.lang") Returns: a `StackWalker` configured with the given options Throws: `[SecurityException](../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager exists and its`checkPermission` method denies access. * #### getInstance public static [StackWalker](../../java/lang/StackWalker.html "class in java.lang") getInstance([Set](../../java/util/Set.html "interface in java.util")<[StackWalker.Option](../../java/lang/StackWalker.Option.html "enum in java.lang")> options, int estimateDepth) Returns a `StackWalker` instance with the given `options` specifying the stack frame information it can access. If the given `options` is empty, this `StackWalker` is configured to skip all[hidden frames](../../java/lang/StackWalker.Option.html#SHOW%5FHIDDEN%5FFRAMES) and no[class reference](../../java/lang/StackWalker.Option.html#RETAIN%5FCLASS%5FREFERENCE) is retained. If a security manager is present and the given `options` contains[Option.RETAIN\_CLASS\_REFERENCE](../../java/lang/StackWalker.Option.html#RETAIN%5FCLASS%5FREFERENCE), it calls its [checkPermission](../../java/lang/SecurityManager.html#checkPermission-java.security.Permission-) method for `RuntimePermission("getStackWalkerWithClassReference")`. The `estimateDepth` specifies the estimate number of stack frames this `StackWalker` will traverse that the `StackWalker` could use as a hint for the buffer size. Parameters: `options` \- [stack walking options](../../java/lang/StackWalker.Option.html "enum in java.lang") `estimateDepth` \- Estimate number of stack frames to be traversed. Returns: a `StackWalker` configured with the given options Throws: `[IllegalArgumentException](../../java/lang/IllegalArgumentException.html "class in java.lang")` \- if `estimateDepth <= 0` `[SecurityException](../../java/lang/SecurityException.html "class in java.lang")` \- if a security manager exists and its`checkPermission` method denies access. * #### walk public <T> T walk([Function](../../java/util/function/Function.html "interface in java.util.function")<? super [Stream](../../java/util/stream/Stream.html "interface in java.util.stream")<[StackWalker.StackFrame](../../java/lang/StackWalker.StackFrame.html "interface in java.lang")>,? extends T> function) Applies the given function to the stream of `StackFrame`s for the current thread, traversing from the top frame of the stack, which is the method calling this `walk` method. The `StackFrame` stream will be closed when this method returns. When a closed `Stream<StackFrame>` object is reused, `IllegalStateException` will 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 `Function` accepting a `Stream<StackFrame>`, rather than returning a `Stream<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 a `Function` parameter, 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, `IllegalStateException` will be thrown. Type Parameters: `T` \- The type of the result of applying the function to the stream of [stack frame](../../java/lang/StackWalker.StackFrame.html "interface in java.lang"). Parameters: `function` \- a function that takes a stream of[stack frames](../../java/lang/StackWalker.StackFrame.html "interface in java.lang") and returns a result. Returns: the result of applying the function to the stream of[stack frame](../../java/lang/StackWalker.StackFrame.html "interface in java.lang"). * #### forEach public void forEach([Consumer](../../java/util/function/Consumer.html "interface in java.util.function")<? super [StackWalker.StackFrame](../../java/lang/StackWalker.StackFrame.html "interface in java.lang")> action) Performs the given action on each element of `StackFrame` stream of the current thread, traversing from the top frame of the stack, which is the method calling this `forEach` method. This method is equivalent to calling > `walk(s -> { s.forEach(action); return null; });` Parameters: `action` \- an action to be performed on each `StackFrame` of the stack of the current thread * #### getCallerClass public [Class](../../java/lang/Class.html "class in java.lang")<?> getCallerClass() Gets the `Class` object of the caller who invoked the method that invoked `getCallerClass`. This method filters [reflection frames](../../java/lang/StackWalker.Option.html#SHOW%5FREFLECT%5FFRAMES), [MethodHandle](../../java/lang/invoke/MethodHandle.html "class in java.lang.invoke"), and[hidden frames](../../java/lang/StackWalker.Option.html#SHOW%5FHIDDEN%5FFRAMES) regardless of the[SHOW\_REFLECT\_FRAMES](../../java/lang/StackWalker.Option.html#SHOW%5FREFLECT%5FFRAMES) and [SHOW\_HIDDEN\_FRAMES](../../java/lang/StackWalker.Option.html#SHOW%5FHIDDEN%5FFRAMES) options this `StackWalker` has 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,`IllegalCallerException` will be thrown. This method throws `UnsupportedOperationException` if this `StackWalker` is not configured with the[RETAIN\_CLASS\_REFERENCE](../../java/lang/StackWalker.Option.html#RETAIN%5FCLASS%5FREFERENCE) option. API Note: For example, `Util::getResourceBundle` loads a resource bundle on behalf of the caller. It invokes `getCallerClass` to identify the class whose method called `Util::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 is `MyTool`. ``` class 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"); } } ``` An equivalent way to find the caller class using the[walk](../../java/lang/StackWalker.html#walk-java.util.function.Function-) method is as follows (filtering the reflection frames, `MethodHandle` and hidden frames not shown below): ``` Optional<Class<?>> caller = walker.walk(s -> s.map(StackFrame::getDeclaringClass) .skip(2) .findFirst()); ``` When the `getCallerClass` method is called from a method that is the bottom most frame on the stack, for example, `static public void main` method launched by the`java` launcher, or a method invoked from a JNI attached thread,`IllegalCallerException` is thrown. Returns: `Class` object of the caller's caller invoking this method. Throws: `[UnsupportedOperationException](../../java/lang/UnsupportedOperationException.html "class in java.lang")` \- if this `StackWalker` is not configured with [Option.RETAIN\_CLASS\_REFERENCE](../../java/lang/StackWalker.Option.html#RETAIN%5FCLASS%5FREFERENCE). `[IllegalCallerException](../../java/lang/IllegalCallerException.html "class in java.lang")` \- if there is no caller frame, i.e. when this `getCallerClass` method is called from a method which is the last frame on the stack.
Report a bug or suggest an enhancement
For further API reference and developer documentation see the Java SE Documentation, which contains more detailed, developer-targeted descriptions with conceptual overviews, definitions of terms, workarounds, and working code examples.
Java is a trademark or registered trademark of Oracle and/or its affiliates in the US and other countries.
Copyright © 1993, 2017, Oracle and/or its affiliates, 500 Oracle Parkway, Redwood Shores, CA 94065 USA.
All rights reserved. Use is subject to license terms and the documentation redistribution policy.