StackWalker::getCallerClass throws UnsupportedOperationException

mandy chung mandy.chung at oracle.com
Tue Sep 4 17:58:43 UTC 2018


Thanks for reporting this.   I have created:
    https://bugs.openjdk.java.net/browse/JDK-8210375

and will look into it.

Mandy

On 9/4/18 4:26 AM, Michael Rasmussen wrote:
> Hi
>
> StackWalker::getCallerClass can throw "UnsupportedOperationException: StackWalker::getCallerClass called from @CallerSensitive", depending on how the underlying fetchNextBatch/fill_in_frames splits the stacktrace.
>
> This seems to be a result of what was introduced in JDK-8157464.
>
> The following code example produces the exception (Tested on the jdk.java.net releases of OpenJDK 10 and 11-ea build 28):
>
> // ----- snip ----
> package com.test;
>
> import java.lang.reflect.Method;
>
> public class Main {
>    public static void main(String[] args) throws Exception {
>      Method method = Main.class.getDeclaredMethod("bar");
>      Method m = Method.class.getMethod("invoke", Object.class, Object[].class);
>
>      // get 'm' past compilation threshold
>      for (int i = 0; i < 15; i++) {
>        m.invoke(Main.class.getDeclaredMethod("dummy"), null, null);
>      }
>
>      m.invoke(m, m, new Object[] {method, new Object[] {null, null}});
>    }
>
>    static void dummy() { }
>
>    static void bar() {
>      System.out.println(StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE).getCallerClass());
>    }
> }
> // ----- snip ----
>
> The above code is constructed so Method::invoke ends up as the frame for which index==start_index in fill_in_frames, thus causing the exception.
>
> For example output, including stackwalk debug output, see below.
>
> // ----- snip ----
> $ java -Xlog:stackwalk=debug com.test.Main
> [0.154s][debug][stackwalk] Start walking: mode 6 skip 0 frames batch size 6
> [0.155s][debug][stackwalk]   skip  java.lang.StackStreamFactory$AbstractStackWalker::callStackWalk
> [0.156s][debug][stackwalk]   skip  java.lang.StackStreamFactory$AbstractStackWalker::beginStackWalk
> [0.157s][debug][stackwalk]   skip  java.lang.StackStreamFactory$AbstractStackWalker::walk
> [0.158s][debug][stackwalk]   skip  java.lang.StackStreamFactory$CallerClassFinder::findCaller
> [0.159s][debug][stackwalk]   skip  java.lang.StackWalker::getCallerClass
> [0.160s][debug][stackwalk] fill_in_frames limit=6 start=2 frames length=8
> [0.161s][debug][stackwalk]   2: frame method:  com.test.Main::bar bci=9
> [0.162s][debug][stackwalk]   3: frame method:  jdk.internal.reflect.NativeMethodAccessorImpl::invoke0 bci=0
> [0.162s][debug][stackwalk]   4: frame method:  jdk.internal.reflect.NativeMethodAccessorImpl::invoke bci=100
> [0.163s][debug][stackwalk]   5: frame method:  jdk.internal.reflect.DelegatingMethodAccessorImpl::invoke bci=6
> [0.163s][debug][stackwalk]   6: frame method:  java.lang.reflect.Method::invoke bci=59
> [0.168s][debug][stackwalk]   7: frame method:  jdk.internal.reflect.GeneratedMethodAccessor1::invoke bci=48
> [0.169s][debug][stackwalk] StackWalk::fetchNextBatch frame_count 8 existing_stream 0x000000a5b8ffb5f0 start 2 frames 10
> [0.170s][debug][stackwalk] fill_in_frames limit=8 start=2 frames length=10
> [0.171s][debug][stackwalk]   2: frame method:  jdk.internal.reflect.DelegatingMethodAccessorImpl::invoke bci=6
> [0.171s][debug][stackwalk]   3: frame method:  java.lang.reflect.Method::invoke bci=59
> [0.172s][debug][stackwalk]   4: frame method:  jdk.internal.reflect.GeneratedMethodAccessor1::invoke bci=48
> [0.173s][debug][stackwalk]   5: frame method:  jdk.internal.reflect.DelegatingMethodAccessorImpl::invoke bci=6
> [0.174s][debug][stackwalk]   6: frame method:  java.lang.reflect.Method::invoke bci=59
> [0.175s][debug][stackwalk]   7: frame method:  jdk.internal.reflect.NativeMethodAccessorImpl::invoke0 bci=0
> [0.175s][debug][stackwalk]   8: frame method:  jdk.internal.reflect.NativeMethodAccessorImpl::invoke bci=100
> [0.179s][debug][stackwalk]   9: frame method:  jdk.internal.reflect.DelegatingMethodAccessorImpl::invoke bci=6
> [0.180s][debug][stackwalk] StackWalk::fetchNextBatch frame_count 8 existing_stream 0x000000a5b8ffb5f0 start 2 frames 10
> [0.181s][debug][stackwalk] fill_in_frames limit=8 start=2 frames length=10
> [0.181s][debug][stackwalk]   2: frame method:  java.lang.reflect.Method::invoke bci=59
> Exception in thread "main" java.lang.reflect.InvocationTargetException
>          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>          at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>          at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>          at com.test.Main.main(Main.java:15)
> Caused by: java.lang.reflect.InvocationTargetException
>          at java.base/jdk.internal.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>          at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>          at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>          ... 5 more
> Caused by: java.lang.reflect.InvocationTargetException
>          at java.base/jdk.internal.reflect.GeneratedMethodAccessor1.invoke(Unknown Source)
>          at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>          at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>          ... 8 more
> Caused by: java.lang.reflect.InvocationTargetException
>          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>          at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>          at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>          at java.base/java.lang.reflect.Method.invoke(Method.java:566)
>          ... 11 more
> Caused by: java.lang.UnsupportedOperationException: StackWalker::getCallerClass called from @CallerSensitive java.lang.reflect.Method.invoke(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object; method
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.fetchStackFrames(Native Method)
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.fetchStackFrames(StackStreamFactory.java:386)
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.getNextBatch(StackStreamFactory.java:322)
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.peekFrame(StackStreamFactory.java:263)
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.hasNext(StackStreamFactory.java:351)
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.nextFrame(StackStreamFactory.java:336)
>          at java.base/java.lang.StackStreamFactory$CallerClassFinder.consumeFrames(StackStreamFactory.java:683)
>          at java.base/java.lang.StackStreamFactory$CallerClassFinder.consumeFrames(StackStreamFactory.java:612)
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.doStackWalk(StackStreamFactory.java:306)
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.callStackWalk(Native Method)
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.beginStackWalk(StackStreamFactory.java:370)
>          at java.base/java.lang.StackStreamFactory$AbstractStackWalker.walk(StackStreamFactory.java:243)
>          at java.base/java.lang.StackStreamFactory$CallerClassFinder.findCaller(StackStreamFactory.java:670)
>          at java.base/java.lang.StackWalker.getCallerClass(StackWalker.java:600)
>          at com.test.Main.bar(Main.java:21)
>          ... 15 more
> // ----- snip ----
>
> Kind regards
> /Michael



More information about the core-libs-dev mailing list