StackerWalker.Option enum has three elements, we have seen the use of RETAIN_CLASS_REFERENCE in previous examples already. In following examples we will see the use of the other two options i.e. SHOW_HIDDEN_FRAMES and SHOW_REFLECT_FRAMES .
Using SHOW_REFLECT_FRAMES
By default, reflection stack frames are hidden when using StackWalker.forEach() or StackWalker.walk() methods. A StackWalker instance configured with this option will show all reflection frames.
Example
public class StackWalkerReflectFrameExample {
public static void main(String[] args) throws Exception {
Method method1 = StackWalkerReflectFrameExample.class
.getMethod("doSomething");
method1.invoke(null);
Method method2 = StackWalkerReflectFrameExample.class
.getMethod("doSomething2");
method2.invoke(null);
}
public static void doSomething() {
System.out.println(" -- without SHOW_REFLECT_FRAMES --");
StackWalker stackWalker = StackWalker.getInstance();
stackWalker.forEach(System.out::println);
}
public static void doSomething2() {
System.out.println(" -- with SHOW_REFLECT_FRAMES --");
StackWalker stackWalker = StackWalker.getInstance(StackWalker.Option.SHOW_REFLECT_FRAMES);
stackWalker.forEach(System.out::println);
}
} Output -- without SHOW_REFLECT_FRAMES -- com.logicbig.example.StackWalkerReflectFrameExample.doSomething(StackWalkerReflectFrameExample.java:20) com.logicbig.example.StackWalkerReflectFrameExample.main(StackWalkerReflectFrameExample.java:10) -- with SHOW_REFLECT_FRAMES -- com.logicbig.example.StackWalkerReflectFrameExample.doSomething2(StackWalkerReflectFrameExample.java:26) java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) java.base/java.lang.reflect.Method.invoke(Method.java:564) com.logicbig.example.StackWalkerReflectFrameExample.main(StackWalkerReflectFrameExample.java:14)
Using SHOW_HIDDEN_FRAMES
JVM may hide implementation specific frames. A StackWalker instance configured with SHOW_HIDDEN_FRAMES option will show all hidden frames. Other than implementation specific frames, this option will also show all reflection frames (as we saw in above example).
Example
In this example, we are going to use StackWalker.forEach() method within a lambda expression. Lambda runtime invocation is JVM implementation specific (see tutorial here) so their stack frames are hidden by default. Let's use SHOW_HIDDEN_FRAMES option to enable them.
public class StackWalkerHiddenFrameExample {
public static void main(String[] args) {
doSomething();
doSomething2();
}
private static void doSomething() {
System.out.println(" -- without SHOW_HIDDEN_FRAMES --");
Stream.of("1").forEach((String s) -> {
StackWalker stackWalker = StackWalker.getInstance();
stackWalker.forEach(System.out::println);
});
}
private static void doSomething2() {
System.out.println(" -- with SHOW_HIDDEN_FRAMES --");
Stream.of("1").forEach((String s) -> {
StackWalker stackWalker = StackWalker.getInstance(StackWalker.Option.SHOW_HIDDEN_FRAMES);
stackWalker.forEach(System.out::println);
});
}
} Output -- without SHOW_HIDDEN_FRAMES -- com.logicbig.example.StackWalkerHiddenFrameExample.lambda$doSomething$0(StackWalkerHiddenFrameExample.java:15) java.base/java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411) java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:591) com.logicbig.example.StackWalkerHiddenFrameExample.doSomething(StackWalkerHiddenFrameExample.java:13) com.logicbig.example.StackWalkerHiddenFrameExample.main(StackWalkerHiddenFrameExample.java:7) -- with SHOW_HIDDEN_FRAMES -- com.logicbig.example.StackWalkerHiddenFrameExample.lambda$doSomething2$1(StackWalkerHiddenFrameExample.java:23) com.logicbig.example.StackWalkerHiddenFrameExample$$Lambda$4/1239731077.accept(Unknown Source) java.base/java.util.stream.Streams$StreamBuilderImpl.forEachRemaining(Streams.java:411) java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:591) com.logicbig.example.StackWalkerHiddenFrameExample.doSomething2(StackWalkerHiddenFrameExample.java:21) com.logicbig.example.StackWalkerHiddenFrameExample.main(StackWalkerHiddenFrameExample.java:8)
As seen above, the second frame shows lambda specific trace (when SHOW_HIDDEN_FRAME specified).
StackWalker.getCallerClass() method and above Options
StackWalker.getCallerClass() method will always filter reflection frames and hidden frames even though SHOW_REFLECT_FRAMES and SHOW_HIDDEN_FRAMES options are specified.
Using Multiple options
StackWalker provides another overloaded getInstance() method which accepts a Set of Options . This can be used to apply multiple options with a single instance.
Example
In this example we are going to specify SHOW_HIDDEN_FRAMES and RETAIN_CLASS_REFERENCE at the same time:
public class MultipleOptionsExample {
public static void main(String[] args) throws Exception {
Method method = MultipleOptionsExample.class
.getMethod("doSomething");
method.invoke(null);
}
public static void doSomething() {
StackWalker stackWalker = StackWalker.getInstance(
Set.of(StackWalker.Option.SHOW_HIDDEN_FRAMES,
StackWalker.Option.RETAIN_CLASS_REFERENCE));
stackWalker.forEach(stackFrame ->
System.out.println(stackFrame.getDeclaringClass().getName()));
}
} Outputcom.logicbig.example.MultipleOptionsExample jdk.internal.reflect.NativeMethodAccessorImpl jdk.internal.reflect.NativeMethodAccessorImpl jdk.internal.reflect.DelegatingMethodAccessorImpl java.lang.reflect.Method com.logicbig.example.MultipleOptionsExample
Example ProjectDependencies and Technologies Used: |