< prev index next >

src/java.base/share/classes/java/lang/StackWalker.java

Print this page

 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package java.lang;
 26 
 27 import jdk.internal.reflect.CallerSensitive;
 28 
 29 import java.lang.invoke.MethodType;
 30 import java.util.EnumSet;
 31 import java.util.Objects;
 32 import java.util.Set;
 33 import java.util.function.Consumer;
 34 import java.util.function.Function;
 35 import java.util.stream.Stream;


 36 
 37 /**
 38  * A stack walker.
 39  *
 40  * <p> The {@link StackWalker#walk walk} method opens a sequential stream
 41  * of {@link StackFrame StackFrame}s for the current thread and then applies
 42  * the given function to walk the {@code StackFrame} stream.
 43  * The stream reports stack frame elements in order, from the top most frame
 44  * that represents the execution point at which the stack was generated to
 45  * the bottom most frame.
 46  * The {@code StackFrame} stream is closed when the {@code walk} method returns.
 47  * If an attempt is made to reuse the closed stream,
 48  * {@code IllegalStateException} will be thrown.
 49  *
 50  * <p> The {@linkplain Option <em>stack walking options</em>} of a
 51  * {@code StackWalker} determines the information of
 52  * {@link StackFrame StackFrame} objects to be returned.
 53  * By default, stack frames of the reflection API and implementation
 54  * classes are {@linkplain Option#SHOW_HIDDEN_FRAMES hidden}
 55  * and {@code StackFrame}s have the class name and method name

207          * {@code class} file as defined by <cite>The Java Virtual Machine
208          * Specification</cite>.
209          *
210          * @return the line number of the source line containing the execution
211          *         point represented by this stack frame, or a negative number if
212          *         this information is unavailable.
213          *
214          * @jvms 4.7.12 The {@code LineNumberTable} Attribute
215          */
216         public int getLineNumber();
217 
218         /**
219          * Returns {@code true} if the method containing the execution point
220          * represented by this stack frame is a native method.
221          *
222          * @return {@code true} if the method containing the execution point
223          *         represented by this stack frame is a native method.
224          */
225         public boolean isNativeMethod();
226 












227         /**
228          * Gets a {@code StackTraceElement} for this stack frame.
229          *
230          * @return {@code StackTraceElement} for this stack frame.
231          */
232         public StackTraceElement toStackTraceElement();
233     }
234 
235     /**
236      * Stack walker option to configure the {@linkplain StackFrame stack frame}
237      * information obtained by a {@code StackWalker}.
238      *
239      * @since 9
240      */
241     public enum Option {
242         /**
243          * Retains {@code Class} object in {@code StackFrame}s
244          * walked by this {@code StackWalker}.
245          *
246          * <p> A {@code StackWalker} configured with this option will support

261          * <p>The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
262          * reflection frames and it will also show other hidden frames that
263          * are implementation-specific.
264          *
265          * @apiNote
266          * This option includes the stack frames representing the invocation of
267          * {@code Method} and {@code Constructor}.  Any utility methods that
268          * are equivalent to calling {@code Method.invoke} or
269          * {@code Constructor.newInstance} such as {@code Class.newInstance}
270          * are not filtered or controlled by any stack walking option.
271          */
272         SHOW_REFLECT_FRAMES,
273         /**
274          * Shows all hidden frames.
275          *
276          * <p>A Java Virtual Machine implementation may hide implementation
277          * specific frames in addition to {@linkplain #SHOW_REFLECT_FRAMES
278          * reflection frames}. A {@code StackWalker} with this {@code SHOW_HIDDEN_FRAMES}
279          * option will show all hidden frames (including reflection frames).
280          */
281         SHOW_HIDDEN_FRAMES;
282     }
283 
284     enum ExtendedOption {
285         /**
286          * Obtain monitors, locals and operands.
287          */
288         LOCALS_AND_OPERANDS
289     };
290 
291     static final EnumSet<Option> DEFAULT_EMPTY_OPTION = EnumSet.noneOf(Option.class);
292 
293     private static final StackWalker DEFAULT_WALKER =
294         new StackWalker(DEFAULT_EMPTY_OPTION);
295 


296     private final Set<Option> options;
297     private final ExtendedOption extendedOption;
298     private final int estimateDepth;
299     final boolean retainClassRef; // cached for performance
300 
301     /**
302      * Returns a {@code StackWalker} instance.
303      *
304      * <p> This {@code StackWalker} is configured to skip all
305      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
306      * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
307      *
308      * @return a {@code StackWalker} configured to skip all
309      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
310      * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
311      *
312      */
313     public static StackWalker getInstance() {
314         // no permission check needed
315         return DEFAULT_WALKER;
316     }
317 


















318     /**
319      * Returns a {@code StackWalker} instance with the given option specifying
320      * the stack frame information it can access.
321      *
322      * <p>
323      * If a security manager is present and the given {@code option} is
324      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
325      * it calls its {@link SecurityManager#checkPermission checkPermission}
326      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
327      *
328      * @param option {@link Option stack walking option}
329      *
330      * @return a {@code StackWalker} configured with the given option
331      *
332      * @throws SecurityException if a security manager exists and its
333      *         {@code checkPermission} method denies access.
334      */
335     public static StackWalker getInstance(Option option) {
336         return getInstance(EnumSet.of(Objects.requireNonNull(option)));
337     }
338 






















339     /**
340      * Returns a {@code StackWalker} instance with the given {@code options} specifying
341      * the stack frame information it can access.  If the given {@code options}
342      * is empty, this {@code StackWalker} is configured to skip all
343      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
344      * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
345      *
346      * <p>
347      * If a security manager is present and the given {@code options} contains
348      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
349      * it calls its {@link SecurityManager#checkPermission checkPermission}
350      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
351      *
352      * @param options {@link Option stack walking option}
353      *
354      * @return a {@code StackWalker} configured with the given options
355      *
356      * @throws SecurityException if a security manager exists and its
357      *         {@code checkPermission} method denies access.
358      */
359     public static StackWalker getInstance(Set<Option> options) {
360         if (options.isEmpty()) {

























361             return DEFAULT_WALKER;
362         }
363 
364         EnumSet<Option> optionSet = toEnumSet(options);
365         checkPermission(optionSet);
366         return new StackWalker(optionSet);
367     }
368 
369     /**
370      * Returns a {@code StackWalker} instance with the given {@code options} specifying
371      * the stack frame information it can access. If the given {@code options}
372      * is empty, this {@code StackWalker} is configured to skip all
373      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
374      * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
375      *
376      * <p>
377      * If a security manager is present and the given {@code options} contains
378      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
379      * it calls its {@link SecurityManager#checkPermission checkPermission}
380      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
381      *
382      * <p>
383      * The {@code estimateDepth} specifies the estimate number of stack frames
384      * this {@code StackWalker} will traverse that the {@code StackWalker} could
385      * use as a hint for the buffer size.
386      *
387      * @param options {@link Option stack walking options}
388      * @param estimateDepth Estimate number of stack frames to be traversed.
389      *
390      * @return a {@code StackWalker} configured with the given options
391      *
392      * @throws IllegalArgumentException if {@code estimateDepth <= 0}
393      * @throws SecurityException if a security manager exists and its
394      *         {@code checkPermission} method denies access.
395      */
396     public static StackWalker getInstance(Set<Option> options, int estimateDepth) {
397         if (estimateDepth <= 0) {
398             throw new IllegalArgumentException("estimateDepth must be > 0");
399         }
400         EnumSet<Option> optionSet = toEnumSet(options);
401         checkPermission(optionSet);
402         return new StackWalker(optionSet, estimateDepth);
403     }
404 
405     // ----- private constructors ------
406     private StackWalker(EnumSet<Option> options) {
407         this(options, 0, null);






408     }
409     private StackWalker(EnumSet<Option> options, int estimateDepth) {
410         this(options, estimateDepth, null);
411     }
412     private StackWalker(EnumSet<Option> options, int estimateDepth, ExtendedOption extendedOption) {













413         this.options = options;
414         this.estimateDepth = estimateDepth;
415         this.extendedOption = extendedOption;
416         this.retainClassRef = hasOption(Option.RETAIN_CLASS_REFERENCE);


417     }
418 
419     private static void checkPermission(Set<Option> options) {
420         Objects.requireNonNull(options);
421         @SuppressWarnings("removal")
422         SecurityManager sm = System.getSecurityManager();
423         if (sm != null) {
424             if (options.contains(Option.RETAIN_CLASS_REFERENCE)) {
425                 sm.checkPermission(new RuntimePermission("getStackWalkerWithClassReference"));
426             }
427         }
428     }
429 
430     /*
431      * Returns a defensive copy
432      */
433     private static EnumSet<Option> toEnumSet(Set<Option> options) {
434         Objects.requireNonNull(options);
435         if (options.isEmpty()) {
436             return DEFAULT_EMPTY_OPTION;

580      * is the bottom most frame on the stack,
581      * for example, {@code static public void main} method launched by the
582      * {@code java} launcher, or a method invoked from a JNI attached thread,
583      * {@code IllegalCallerException} is thrown.
584      *
585      * @return {@code Class} object of the caller's caller invoking this method.
586      *
587      * @throws UnsupportedOperationException if this {@code StackWalker}
588      *         is not configured with {@link Option#RETAIN_CLASS_REFERENCE
589      *         Option.RETAIN_CLASS_REFERENCE}.
590      * @throws IllegalCallerException if there is no caller frame, i.e.
591      *         when this {@code getCallerClass} method is called from a method
592      *         which is the last frame on the stack.
593      */
594     @CallerSensitive
595     public Class<?> getCallerClass() {
596         if (!retainClassRef) {
597             throw new UnsupportedOperationException("This stack walker " +
598                     "does not have RETAIN_CLASS_REFERENCE access");
599         }



600 
601         return StackStreamFactory.makeCallerFinder(this).findCaller();
602     }
603 
604     // ---- package access ----
605 
606     static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption) {










607         EnumSet<Option> optionSet = toEnumSet(options);
608         checkPermission(optionSet);
609         return new StackWalker(optionSet, 0, extendedOption);
610     }
611 
612     int estimateDepth() {
613         return estimateDepth;
614     }
615 
616     boolean hasOption(Option option) {
617         return options.contains(option);
618     }
619 
620     boolean hasLocalsOperandsOption() {
621         return extendedOption == ExtendedOption.LOCALS_AND_OPERANDS;
622     }








623 }

 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package java.lang;
 26 
 27 import jdk.internal.reflect.CallerSensitive;
 28 
 29 import java.lang.invoke.MethodType;
 30 import java.util.EnumSet;
 31 import java.util.Objects;
 32 import java.util.Set;
 33 import java.util.function.Consumer;
 34 import java.util.function.Function;
 35 import java.util.stream.Stream;
 36 import jdk.internal.vm.Continuation;
 37 import jdk.internal.vm.ContinuationScope;
 38 
 39 /**
 40  * A stack walker.
 41  *
 42  * <p> The {@link StackWalker#walk walk} method opens a sequential stream
 43  * of {@link StackFrame StackFrame}s for the current thread and then applies
 44  * the given function to walk the {@code StackFrame} stream.
 45  * The stream reports stack frame elements in order, from the top most frame
 46  * that represents the execution point at which the stack was generated to
 47  * the bottom most frame.
 48  * The {@code StackFrame} stream is closed when the {@code walk} method returns.
 49  * If an attempt is made to reuse the closed stream,
 50  * {@code IllegalStateException} will be thrown.
 51  *
 52  * <p> The {@linkplain Option <em>stack walking options</em>} of a
 53  * {@code StackWalker} determines the information of
 54  * {@link StackFrame StackFrame} objects to be returned.
 55  * By default, stack frames of the reflection API and implementation
 56  * classes are {@linkplain Option#SHOW_HIDDEN_FRAMES hidden}
 57  * and {@code StackFrame}s have the class name and method name

209          * {@code class} file as defined by <cite>The Java Virtual Machine
210          * Specification</cite>.
211          *
212          * @return the line number of the source line containing the execution
213          *         point represented by this stack frame, or a negative number if
214          *         this information is unavailable.
215          *
216          * @jvms 4.7.12 The {@code LineNumberTable} Attribute
217          */
218         public int getLineNumber();
219 
220         /**
221          * Returns {@code true} if the method containing the execution point
222          * represented by this stack frame is a native method.
223          *
224          * @return {@code true} if the method containing the execution point
225          *         represented by this stack frame is a native method.
226          */
227         public boolean isNativeMethod();
228 
229         /**
230          * Returns the name of the {@link ContinuationScope} of the continuation 
231          * (if any) in which this frame exists.
232          * 
233          * @return the name of the {@link ContinuationScope} of the continuation 
234          *         in which this frame exists or {@code null} if this frame is 
235          *         not in a continuation.
236          */
237         public default String getContinuationScopeName() {
238             return null;
239         }
240 
241         /**
242          * Gets a {@code StackTraceElement} for this stack frame.
243          *
244          * @return {@code StackTraceElement} for this stack frame.
245          */
246         public StackTraceElement toStackTraceElement();
247     }
248 
249     /**
250      * Stack walker option to configure the {@linkplain StackFrame stack frame}
251      * information obtained by a {@code StackWalker}.
252      *
253      * @since 9
254      */
255     public enum Option {
256         /**
257          * Retains {@code Class} object in {@code StackFrame}s
258          * walked by this {@code StackWalker}.
259          *
260          * <p> A {@code StackWalker} configured with this option will support

275          * <p>The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
276          * reflection frames and it will also show other hidden frames that
277          * are implementation-specific.
278          *
279          * @apiNote
280          * This option includes the stack frames representing the invocation of
281          * {@code Method} and {@code Constructor}.  Any utility methods that
282          * are equivalent to calling {@code Method.invoke} or
283          * {@code Constructor.newInstance} such as {@code Class.newInstance}
284          * are not filtered or controlled by any stack walking option.
285          */
286         SHOW_REFLECT_FRAMES,
287         /**
288          * Shows all hidden frames.
289          *
290          * <p>A Java Virtual Machine implementation may hide implementation
291          * specific frames in addition to {@linkplain #SHOW_REFLECT_FRAMES
292          * reflection frames}. A {@code StackWalker} with this {@code SHOW_HIDDEN_FRAMES}
293          * option will show all hidden frames (including reflection frames).
294          */
295         SHOW_HIDDEN_FRAMES,
296     }
297 
298     enum ExtendedOption {
299         /**
300          * Obtain monitors, locals and operands.
301          */
302         LOCALS_AND_OPERANDS
303     };
304 
305     static final EnumSet<Option> DEFAULT_EMPTY_OPTION = EnumSet.noneOf(Option.class);
306 
307     private static final StackWalker DEFAULT_WALKER =
308         new StackWalker(DEFAULT_EMPTY_OPTION);
309 
310     private final Continuation continuation;
311     private final ContinuationScope contScope;
312     private final Set<Option> options;
313     private final ExtendedOption extendedOption;
314     private final int estimateDepth;
315     final boolean retainClassRef; // cached for performance
316 
317     /**
318      * Returns a {@code StackWalker} instance.
319      *
320      * <p> This {@code StackWalker} is configured to skip all
321      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
322      * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
323      *
324      * @return a {@code StackWalker} configured to skip all
325      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
326      * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
327      *
328      */
329     public static StackWalker getInstance() {
330         // no permission check needed
331         return DEFAULT_WALKER;
332     }
333 
334     /**
335      * Returns a {@code StackWalker} instance.
336      *
337      * <p> This {@code StackWalker} is configured to skip all
338      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
339      * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
340      * 
341      * @param contScope the continuation scope up to which (inclusive) to walk the stack
342      * 
343      * @return a {@code StackWalker} configured to skip all
344      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and
345      * no {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
346      *
347      */
348     static StackWalker getInstance(ContinuationScope contScope) {
349         return getInstance(EnumSet.noneOf(Option.class), contScope);
350     }
351 
352     /**
353      * Returns a {@code StackWalker} instance with the given option specifying
354      * the stack frame information it can access.
355      *
356      * <p>
357      * If a security manager is present and the given {@code option} is
358      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
359      * it calls its {@link SecurityManager#checkPermission checkPermission}
360      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
361      *
362      * @param option {@link Option stack walking option}
363      *
364      * @return a {@code StackWalker} configured with the given option
365      *
366      * @throws SecurityException if a security manager exists and its
367      *         {@code checkPermission} method denies access.
368      */
369     public static StackWalker getInstance(Option option) {
370         return getInstance(EnumSet.of(Objects.requireNonNull(option)));
371     }
372 
373    /**
374      * Returns a {@code StackWalker} instance with the given option specifying
375      * the stack frame information it can access.
376      *
377      * <p>
378      * If a security manager is present and the given {@code option} is
379      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
380      * it calls its {@link SecurityManager#checkPermission checkPermission}
381      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
382      *
383      * @param option {@link Option stack walking option}
384      * @param contScope the continuation scope up to which (inclusive) to walk the stack
385      *
386      * @return a {@code StackWalker} configured with the given option
387      *
388      * @throws SecurityException if a security manager exists and its
389      *         {@code checkPermission} method denies access.
390      */
391     static StackWalker getInstance(Option option, ContinuationScope contScope) {
392         return getInstance(EnumSet.of(Objects.requireNonNull(option)), contScope);
393     }
394 
395     /**
396      * Returns a {@code StackWalker} instance with the given {@code options} specifying
397      * the stack frame information it can access.  If the given {@code options}
398      * is empty, this {@code StackWalker} is configured to skip all
399      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
400      * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
401      *
402      * <p>
403      * If a security manager is present and the given {@code options} contains
404      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
405      * it calls its {@link SecurityManager#checkPermission checkPermission}
406      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
407      *
408      * @param options {@link Option stack walking option}
409      *
410      * @return a {@code StackWalker} configured with the given options
411      *
412      * @throws SecurityException if a security manager exists and its
413      *         {@code checkPermission} method denies access.
414      */
415     public static StackWalker getInstance(Set<Option> options) {
416         return getInstance(options, null);
417     }
418 
419     /**
420      * Returns a {@code StackWalker} instance with the given {@code options} specifying
421      * the stack frame information it can access.  If the given {@code options}
422      * is empty, this {@code StackWalker} is configured to skip all
423      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
424      * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
425      *
426      * <p>
427      * If a security manager is present and the given {@code options} contains
428      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
429      * it calls its {@link SecurityManager#checkPermission checkPermission}
430      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
431      *
432      * @param options {@link Option stack walking option}
433      * @param contScope the continuation scope up to which (inclusive) to walk the stack
434      *
435      * @return a {@code StackWalker} configured with the given options
436      *
437      * @throws SecurityException if a security manager exists and its
438      *         {@code checkPermission} method denies access.
439      */
440     static StackWalker getInstance(Set<Option> options, ContinuationScope contScope) {
441         if (options.isEmpty() && contScope == null) {
442             return DEFAULT_WALKER;
443         }
444 
445         EnumSet<Option> optionSet = toEnumSet(options);
446         checkPermission(optionSet);
447         return new StackWalker(optionSet, contScope);
448     }
449 
450     /**
451      * Returns a {@code StackWalker} instance with the given {@code options} specifying
452      * the stack frame information it can access. If the given {@code options}
453      * is empty, this {@code StackWalker} is configured to skip all
454      * {@linkplain Option#SHOW_HIDDEN_FRAMES hidden frames} and no
455      * {@linkplain Option#RETAIN_CLASS_REFERENCE class reference} is retained.
456      *
457      * <p>
458      * If a security manager is present and the given {@code options} contains
459      * {@link Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE},
460      * it calls its {@link SecurityManager#checkPermission checkPermission}
461      * method for {@code RuntimePermission("getStackWalkerWithClassReference")}.
462      *
463      * <p>
464      * The {@code estimateDepth} specifies the estimate number of stack frames
465      * this {@code StackWalker} will traverse that the {@code StackWalker} could
466      * use as a hint for the buffer size.
467      *
468      * @param options {@link Option stack walking options}
469      * @param estimateDepth Estimate number of stack frames to be traversed.
470      *
471      * @return a {@code StackWalker} configured with the given options
472      *
473      * @throws IllegalArgumentException if {@code estimateDepth <= 0}
474      * @throws SecurityException if a security manager exists and its
475      *         {@code checkPermission} method denies access.
476      */
477     public static StackWalker getInstance(Set<Option> options, int estimateDepth) {
478         if (estimateDepth <= 0) {
479             throw new IllegalArgumentException("estimateDepth must be > 0");
480         }
481         EnumSet<Option> optionSet = toEnumSet(options);
482         checkPermission(optionSet);
483         return new StackWalker(optionSet, estimateDepth);
484     }
485 
486     // ----- private constructors ------
487     private StackWalker(EnumSet<Option> options) {
488         this(options, 0, null, null, null);
489     }
490     private StackWalker(EnumSet<Option> options, ContinuationScope contScope) {
491         this(options, 0, null, contScope, null);
492     }
493     private StackWalker(EnumSet<Option> options, ContinuationScope contScope, Continuation continuation) {
494         this(options, 0, null, contScope, continuation);
495     }
496     private StackWalker(EnumSet<Option> options, int estimateDepth) {
497         this(options, estimateDepth, null, null, null);
498     }
499     private StackWalker(EnumSet<Option> options, int estimateDepth, ContinuationScope contScope) {
500         this(options, estimateDepth, null, contScope, null);
501     }
502     private StackWalker(EnumSet<Option> options,
503                         int estimateDepth,
504                         ContinuationScope contScope,
505                         Continuation continuation) {
506         this(options, estimateDepth, null, contScope, continuation);
507     }
508     private StackWalker(EnumSet<Option> options,
509                         int estimateDepth,
510                         ExtendedOption extendedOption,
511                         ContinuationScope contScope,
512                         Continuation continuation) {
513         this.options = options;
514         this.estimateDepth = estimateDepth;
515         this.extendedOption = extendedOption;
516         this.retainClassRef = hasOption(Option.RETAIN_CLASS_REFERENCE);
517         this.contScope = contScope;
518         this.continuation = continuation;
519     }
520 
521     private static void checkPermission(Set<Option> options) {
522         Objects.requireNonNull(options);
523         @SuppressWarnings("removal")
524         SecurityManager sm = System.getSecurityManager();
525         if (sm != null) {
526             if (options.contains(Option.RETAIN_CLASS_REFERENCE)) {
527                 sm.checkPermission(new RuntimePermission("getStackWalkerWithClassReference"));
528             }
529         }
530     }
531 
532     /*
533      * Returns a defensive copy
534      */
535     private static EnumSet<Option> toEnumSet(Set<Option> options) {
536         Objects.requireNonNull(options);
537         if (options.isEmpty()) {
538             return DEFAULT_EMPTY_OPTION;

682      * is the bottom most frame on the stack,
683      * for example, {@code static public void main} method launched by the
684      * {@code java} launcher, or a method invoked from a JNI attached thread,
685      * {@code IllegalCallerException} is thrown.
686      *
687      * @return {@code Class} object of the caller's caller invoking this method.
688      *
689      * @throws UnsupportedOperationException if this {@code StackWalker}
690      *         is not configured with {@link Option#RETAIN_CLASS_REFERENCE
691      *         Option.RETAIN_CLASS_REFERENCE}.
692      * @throws IllegalCallerException if there is no caller frame, i.e.
693      *         when this {@code getCallerClass} method is called from a method
694      *         which is the last frame on the stack.
695      */
696     @CallerSensitive
697     public Class<?> getCallerClass() {
698         if (!retainClassRef) {
699             throw new UnsupportedOperationException("This stack walker " +
700                     "does not have RETAIN_CLASS_REFERENCE access");
701         }
702         if (continuation != null) {
703             throw new UnsupportedOperationException("This stack walker walks a continuation");
704         }
705 
706         return StackStreamFactory.makeCallerFinder(this).findCaller();
707     }
708 
709     // ---- package access ----
710 
711     static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption) {
712         return newInstance(options, extendedOption, null);
713     }
714 
715     static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption, ContinuationScope contScope) {
716         EnumSet<Option> optionSet = toEnumSet(options);
717         checkPermission(optionSet);
718         return new StackWalker(optionSet, 0, extendedOption, contScope, null);
719     }
720 
721     static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption, ContinuationScope contScope, Continuation continuation) {
722         EnumSet<Option> optionSet = toEnumSet(options);
723         checkPermission(optionSet);
724         return new StackWalker(optionSet, 0, extendedOption, contScope, continuation);
725     }
726 
727     int estimateDepth() {
728         return estimateDepth;
729     }
730 
731     boolean hasOption(Option option) {
732         return options.contains(option);
733     }
734 
735     boolean hasLocalsOperandsOption() {
736         return extendedOption == ExtendedOption.LOCALS_AND_OPERANDS;
737     }
738 
739     ContinuationScope getContScope() {
740         return contScope;
741     }
742 
743     Continuation getContinuation() {
744         return continuation;
745     }
746 }
< prev index next >