Java 9 StackWalker - SHOW_HIDDEN_FRAMES and SHOW_REFLECT_FRAMES Options Examples

[Updated: Oct 21, 2017, Created: Oct 19, 2017]

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()));
    }
}

Output

com.logicbig.example.MultipleOptionsExample
jdk.internal.reflect.NativeMethodAccessorImpl
jdk.internal.reflect.NativeMethodAccessorImpl
jdk.internal.reflect.DelegatingMethodAccessorImpl
java.lang.reflect.Method
com.logicbig.example.MultipleOptionsExample

Example Project

Dependencies and Technologies Used :

  • JDK 9
StackWalker using SHOW_HIDDEN_FRAMES and SHOW_REFLECT_FRAMES Select All Download
  • stack-walker-options-examples
    • src
      • com
        • logicbig
          • example

See Also