public final class StackWalker extends Object
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 a
StackWalker determines the information of
StackFrame objects to be returned.
By default, stack frames of the reflection API and implementation
classes are hidden
and StackFrames 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.
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.| Modifier and Type | Class and 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 by
StackWalker. |
| Modifier and Type | Method and 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 invoking the method
that calls this getCallerClass method. |
static StackWalker |
getInstance()
Returns a
StackWalker instance. |
static StackWalker |
getInstance(Set<StackWalker.Option> options)
Returns a
StackWalker instance with the given specifying
the stack frame information it can access. |
static StackWalker |
getInstance(Set<StackWalker.Option> options,
int estimateDepth)
Returns a
StackWalker instance with the given specifying
the stack frame information it can access. |
static StackWalker |
getInstance(StackWalker.Option option)
Returns a
StackWalker instance with the given option specifying
the stack frame information it can access. |
<T> 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. |
public static StackWalker getInstance()
StackWalker instance.
This StackWalker is configured to skip all
hidden frames and
no class reference is retained.
StackWalker configured to skip all
hidden frames and
no class reference is retained.public static StackWalker getInstance(StackWalker.Option option)
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,
it calls its checkPermission
method for StackFramePermission("retainClassReference").
option - stack walking optionStackWalker configured with the given optionSecurityException - if a security manager exists and its
checkPermission method denies access.public static StackWalker getInstance(Set<StackWalker.Option> options)
StackWalker instance with the given specifying
the stack frame information it can access. If the given
is empty, this StackWalker is configured to skip all
hidden frames and no
class reference is retained.
If a security manager is present and the given options contains
Option.RETAIN_CLASS_REFERENCE,
it calls its checkPermission
method for StackFramePermission("retainClassReference").
options - stack walking optionStackWalker configured with the given optionsSecurityException - if a security manager exists and its
checkPermission method denies access.public static StackWalker getInstance(Set<StackWalker.Option> options, int estimateDepth)
StackWalker instance with the given specifying
the stack frame information it can access. If the given
is empty, this StackWalker is configured to skip all
hidden frames and no
class reference is retained.
If a security manager is present and the given options contains
Option.RETAIN_CLASS_REFERENCE,
it calls its checkPermission
method for StackFramePermission("retainClassReference").
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.
options - stack walking optionsestimateDepth - Estimate number of stack frames to be traversed.StackWalker configured with the given optionsIllegalArgumentException - if estimateDepth <= 0SecurityException - if a security manager exists and its
checkPermission method denies access.public <T> T walk(Function<? super Stream<StackWalker.StackFrame>,? extends T> function)
StackFrames
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.
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.
IllegalStateException will be thrown.T - The type of the result of applying the function to the
stream of stack frame.function - a function that takes a stream of
stack frames and returns a result.public void forEach(Consumer<? super StackWalker.StackFrame> action)
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; });
action - an action to be performed on each StackFrame
of the stack of the current threadpublic Class<?> getCallerClass()
Class object of the caller invoking the method
that calls this getCallerClass method.
Reflection frames, MethodHandle and
hidden frames are filtered regardless of the
SHOW_REFLECT_FRAMES
and SHOW_HIDDEN_FRAMES options
this StackWalker has been configured.
This method throws UnsupportedOperationException
if this StackWalker is not configured with
RETAIN_CLASS_REFERENCE option,
This method should be called when a caller frame is present. If
it is called from the last frame on the stack;
IllegalStateException will be thrown.
Util::getResourceBundle loads a resource bundle
on behalf of the caller. It calls this getCallerClass method
to find the method calling Util::getResourceBundle and use the caller's
class loader to load the resource bundle. The caller class in this example
is the MyTool class.
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 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 last 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.
IllegalStateException is thrown.Class object of the caller's caller invoking this method.UnsupportedOperationException - if this StackWalker
is not configured with Option.RETAIN_CLASS_REFERENCE.IllegalStateException - 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. Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2015, Oracle and/or its affiliates. All rights reserved.
DRAFT internal-b00