java.lang.StackWalker Maven / Gradle / Ivy
Show all versions of qbicc-rt-java.base Show documentation
/*
* Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package java.lang;
import jdk.internal.reflect.CallerSensitive;
import java.lang.invoke.MethodType;
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.stream.Stream;
/**
* A stack walker.
*
* The {@link StackWalker#walk walk} method opens a sequential stream
* of {@link StackFrame StackFrame}s for the current thread and then applies
* the given function to walk the {@code 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 {@code StackFrame} stream is closed when the {@code walk} method returns.
* If an attempt is made to reuse the closed stream,
* {@code IllegalStateException} will be thrown.
*
*
The {@linkplain Option stack walking options} of a
* {@code StackWalker} determines the information of
* {@link StackFrame StackFrame} objects to be returned.
* By default, stack frames of the reflection API and implementation
* classes are {@linkplain Option#SHOW_HIDDEN_FRAMES hidden}
* and {@code StackFrame}s have the class name and method name
* available but not the {@link StackFrame#getDeclaringClass() Class reference}.
*
*
{@code StackWalker} is thread-safe. Multiple threads can share
* a single {@code StackWalker} object to traverse its own stack.
* A permission check is performed when a {@code StackWalker} is created,
* according to the options it requests.
* No further permission check is done at stack walking time.
*
* @apiNote
* Examples
*
*
1. To find the first caller filtering a known list of implementation class:
*
{@code
* StackWalker walker = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE);
* Optional> callerClass = walker.walk(s ->
* s.map(StackFrame::getDeclaringClass)
* .filter(interestingClasses::contains)
* .findFirst());
* }
*
* 2. To snapshot the top 10 stack frames of the current thread,
*
{@code
* List stack = StackWalker.getInstance().walk(s ->
* s.limit(10).collect(Collectors.toList()));
* }
*
* Unless otherwise noted, passing a {@code null} argument to a
* constructor or method in this {@code StackWalker} class
* will cause a {@link NullPointerException NullPointerException}
* to be thrown.
*
* @since 9
*/
public final class StackWalker {
/**
* A {@code StackFrame} object represents a method invocation returned by
* {@link StackWalker}.
*
* The {@link #getDeclaringClass()} method may be unsupported as determined
* by the {@linkplain Option stack walking options} of a {@linkplain
* StackWalker stack walker}.
*
* @since 9
* @jvms 2.6
*/
public interface StackFrame {
/**
* Gets the binary name
* of the declaring class of the method represented by this stack frame.
*
* @return the binary name of the declaring class of the method
* represented by this stack frame
*
* @jls 13.1 The Form of a Binary
*/
public String getClassName();
/**
* Gets the name of the method represented by this stack frame.
* @return the name of the method represented by this stack frame
*/
public String getMethodName();
/**
* Gets the declaring {@code Class} for the method represented by
* this stack frame.
*
* @return the declaring {@code Class} of the method represented by
* this stack frame
*
* @throws UnsupportedOperationException if this {@code StackWalker}
* is not configured with {@link Option#RETAIN_CLASS_REFERENCE
* Option.RETAIN_CLASS_REFERENCE}.
*/
public Class> getDeclaringClass();
/**
* Returns the {@link MethodType} representing the parameter types and
* the return type for the method represented by this stack frame.
*
* @implSpec
* The default implementation throws {@code UnsupportedOperationException}.
*
* @return the {@code MethodType} for this stack frame
*
* @throws UnsupportedOperationException if this {@code StackWalker}
* is not configured with {@link Option#RETAIN_CLASS_REFERENCE
* Option.RETAIN_CLASS_REFERENCE}.
*
* @since 10
*/
public default MethodType getMethodType() {
throw new UnsupportedOperationException();
}
/**
* Returns the descriptor of the method represented by
* this stack frame as defined by
* The Java Virtual Machine Specification.
*
* @implSpec
* The default implementation throws {@code UnsupportedOperationException}.
*
* @return the descriptor of the method represented by
* this stack frame
*
* @see MethodType#fromMethodDescriptorString(String, ClassLoader)
* @see MethodType#toMethodDescriptorString()
* @jvms 4.3.3 Method Descriptor
*
* @since 10
*/
public default String getDescriptor() {
throw new UnsupportedOperationException();
}
/**
* Returns the index to the code array of the {@code Code} attribute
* containing the execution point represented by this stack frame.
* The code array gives the actual bytes of Java Virtual Machine code
* that implement the method.
*
* @return the index to the code array of the {@code Code} attribute
* containing the execution point represented by this stack frame,
* or a negative number if the method is native.
*
* @jvms 4.7.3 The {@code Code} Attribute
*/
public int getByteCodeIndex();
/**
* Returns the name of the source file containing the execution point
* represented by this stack frame. Generally, this corresponds
* to the {@code SourceFile} attribute of the relevant {@code class}
* file as defined by The Java Virtual Machine Specification.
* In some systems, the name may refer to some source code unit
* other than a file, such as an entry in a source repository.
*
* @return the name of the file containing the execution point
* represented by this stack frame, or {@code null} if
* this information is unavailable.
*
* @jvms 4.7.10 The {@code SourceFile} Attribute
*/
public String getFileName();
/**
* Returns the line number of the source line containing the execution
* point represented by this stack frame. Generally, this is
* derived from the {@code LineNumberTable} attribute of the relevant
* {@code class} file as defined by The Java Virtual Machine
* Specification.
*
* @return the line number of the source line containing the execution
* point represented by this stack frame, or a negative number if
* this information is unavailable.
*
* @jvms 4.7.12 The {@code LineNumberTable} Attribute
*/
public int getLineNumber();
/**
* Returns {@code true} if the method containing the execution point
* represented by this stack frame is a native method.
*
* @return {@code true} if the method containing the execution point
* represented by this stack frame is a native method.
*/
public boolean isNativeMethod();
/**
* Gets a {@code StackTraceElement} for this stack frame.
*
* @return {@code StackTraceElement} for this stack frame.
*/
public StackTraceElement toStackTraceElement();
}
/**
* Stack walker option to configure the {@linkplain StackFrame stack frame}
* information obtained by a {@code StackWalker}.
*
* @since 9
*/
public enum Option {
/**
* Retains {@code Class} object in {@code StackFrame}s
* walked by this {@code StackWalker}.
*
*
A {@code StackWalker} configured with this option will support
* {@link StackWalker#getCallerClass()} and
* {@link StackFrame#getDeclaringClass() StackFrame.getDeclaringClass()}.
*/
RETAIN_CLASS_REFERENCE,
/**
* Shows all reflection frames.
*
*
By default, reflection frames are hidden. A {@code StackWalker}
* configured with this {@code SHOW_REFLECT_FRAMES} option
* will show all reflection frames that
* include {@link java.lang.reflect.Method#invoke} and
* {@link java.lang.reflect.Constructor#newInstance(Object...)}
* and their reflection implementation classes.
*
*
The {@link #SHOW_HIDDEN_FRAMES} option can also be used to show all
* reflection frames and it will also show other hidden frames that
* are implementation-specific.
*
* @apiNote
* This option includes the stack frames representing the invocation of
* {@code Method} and {@code Constructor}. Any utility methods that
* are equivalent to calling {@code Method.invoke} or
* {@code Constructor.newInstance} such as {@code Class.newInstance}
* are not filtered or controlled by any stack walking option.
*/
SHOW_REFLECT_FRAMES,
/**
* Shows all hidden frames.
*
*
A Java Virtual Machine implementation may hide implementation
* specific frames in addition to {@linkplain #SHOW_REFLECT_FRAMES
* reflection frames}. A {@code StackWalker} with this {@code SHOW_HIDDEN_FRAMES}
* option will show all hidden frames (including reflection frames).
*/
SHOW_HIDDEN_FRAMES;
}
enum ExtendedOption {
/**
* Obtain monitors, locals and operands.
*/
LOCALS_AND_OPERANDS
};
static final EnumSet