Path: blob/master/jcl/src/java.base/share/classes/java/lang/StackTraceElement.java
12513 views
/*[INCLUDE-IF Sidecar16]*/1package java.lang;23import com.ibm.oti.util.Util;45/*******************************************************************************6* Copyright (c) 2002, 2021 IBM Corp. and others7*8* This program and the accompanying materials are made available under9* the terms of the Eclipse Public License 2.0 which accompanies this10* distribution and is available at https://www.eclipse.org/legal/epl-2.0/11* or the Apache License, Version 2.0 which accompanies this distribution and12* is available at https://www.apache.org/licenses/LICENSE-2.0.13*14* This Source Code may also be made available under the following15* Secondary Licenses when the conditions for such availability set16* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU17* General Public License, version 2 with the GNU Classpath18* Exception [1] and GNU General Public License, version 2 with the19* OpenJDK Assembly Exception [2].20*21* [1] https://www.gnu.org/software/classpath/license.html22* [2] http://openjdk.java.net/legal/assembly-exception.html23*24* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception25*******************************************************************************/2627/**28* StackTraceElement represents a stack frame.29*30* @see Throwable#getStackTrace()31*/32public final class StackTraceElement implements java.io.Serializable {33private static final long serialVersionUID = 6992337162326171013L;34/*[IF JAVA_SPEC_VERSION >= 11]*/35private final String moduleName;36private final String moduleVersion;37private final String classLoaderName;38private transient boolean includeClassLoaderName;39private transient boolean includeModuleVersion;40/*[ENDIF] JAVA_SPEC_VERSION >= 11*/41private final String declaringClass;42private final String methodName;43private final String fileName;44private final int lineNumber;45transient Object source;4647/**48* Create a StackTraceElement from the parameters.49*50* @param cls The class name51* @param method The method name52* @param file The file name53* @param line The line number54*/55public StackTraceElement(String cls, String method, String file, int line) {56if (cls == null || method == null) throw new NullPointerException();57/*[IF JAVA_SPEC_VERSION >= 11]*/58moduleName = null;59moduleVersion = null;60classLoaderName = null;61/**62* includeClassLoaderName and includeModuleVersion are initialized to63* true for publicly constructed StackTraceElements, as this information64* is to be included when the element is printed.65*/66includeClassLoaderName = true;67includeModuleVersion = true;68/*[ENDIF] JAVA_SPEC_VERSION >= 11*/69declaringClass = cls;70methodName = method;71fileName = file;72lineNumber = line;73}7475/*[IF JAVA_SPEC_VERSION >= 11]*/76/**77* Create a StackTraceElement from the parameters.78*79* @param classLoaderName The name for the ClassLoader80* @param module The module name81* @param version The module version82* @param cls The class name83* @param method The method name84* @param file The file name85* @param line The line number86* @since 987*/88public StackTraceElement(String classLoaderName, String module, String version, String cls, String method, String file, int line) {89if (cls == null || method == null) throw new NullPointerException();90moduleName = module;91moduleVersion = version;92declaringClass = cls;93methodName = method;94fileName = file;95lineNumber = line;96this.classLoaderName = classLoaderName;97/**98* includeClassLoaderName and includeModuleVersion are initialized to99* true for publicly constructed StackTraceElements, as this information100* is to be included when the element is printed.101*/102includeClassLoaderName = true;103includeModuleVersion = true;104}105106/**107* Returns the name of the ClassLoader used to load the class for the method in the stack frame. See ClassLoader.getName().108* @return name of the Classloader or null109* @since 9110*/111public String getClassLoaderName() {112return classLoaderName;113}114/*[ENDIF] JAVA_SPEC_VERSION >= 11*/115116@SuppressWarnings("unused")117private StackTraceElement() {118/*[IF JAVA_SPEC_VERSION >= 11]*/119moduleName = null;120moduleVersion = null;121classLoaderName = null;122/**123* includeClassLoaderName and includeModuleVersion are initialized to124* false for internally constructed StackTraceElements, as these fields125* are to be set natively.126*/127includeClassLoaderName = false;128includeModuleVersion = false;129/*[ENDIF] JAVA_SPEC_VERSION >= 11*/130declaringClass = null;131methodName = null;132fileName = null;133lineNumber = 0;134} // prevent instantiation from java code - only the VM creates these135136/**137* Returns true if the specified object is another StackTraceElement instance138* representing the same execution point as this instance.139*140* @param obj the object to compare to141*142*/143@Override144public boolean equals(Object obj) {145if (!(obj instanceof StackTraceElement)) return false;146StackTraceElement castObj = (StackTraceElement) obj;147148// Unknown methods are never equal to anything (not strictly to spec, but spec does not allow null method/class names)149if ((methodName == null) || (castObj.methodName == null)) return false;150151if (!getMethodName().equals(castObj.getMethodName())) return false;152if (!getClassName().equals(castObj.getClassName())) return false;153String localFileName = getFileName();154if (localFileName == null) {155if (castObj.getFileName() != null) return false;156} else {157if (!localFileName.equals(castObj.getFileName())) return false;158}159if (getLineNumber() != castObj.getLineNumber()) return false;160161return true;162}163164/*[IF JAVA_SPEC_VERSION >= 11]*/165/**166* Answers the name of the module to which the execution point represented by this stack trace element belongs.167*168* @return the name of the Module or null if it is not available169*/170public String getModuleName() {171return moduleName;172}173174/**175* Answers the version of the module to which the execution point represented by this stack trace element belongs.176*177* @return the version of the Module or null if it is not available.178*/179public String getModuleVersion() {180return moduleVersion;181}182183/**184* Returns whether the classloader name should be included in the stack trace for the provided StackTraceElement.185*186* @return true if the classloader name should be included, false otherwise.187*/188boolean getIncludeClassLoaderName() {189return includeClassLoaderName;190}191192/**193* Returns whether the module version should be included in the stack trace for the provided StackTraceElement.194*195* @return true if the module version should be included, false otherwise.196*/197boolean getIncludeModuleVersion() {198return includeModuleVersion;199}200201/**202* Set the includeClassLoaderName and includeModuleVersion fields for this StackTraceElement.203*204* @param classLoader the classloader for the StackTraceElement.205*/206void setIncludeInfoFlags(ClassLoader classLoader) {207/**208* If the classloader is one of the Platform or Bootstrap built-in classloaders,209* don't include its name or module version in the stack trace. If it is the210* Application/System built-in classloader, don't include the class name, but211* include the module version.212*/213if ((null == classLoader)214|| (ClassLoader.getPlatformClassLoader() == classLoader) // VM: Extension ClassLoader215|| (ClassLoader.bootstrapClassLoader == classLoader) // VM: System ClassLoader216) {217includeClassLoaderName = false;218includeModuleVersion = false;219} else if ((ClassLoader.getSystemClassLoader() == classLoader)) { // VM: Application ClassLoader220includeClassLoaderName = false;221}222}223224/**225* Disable including the classloader name and the module version for this StackTraceElement.226*/227void disableIncludeInfoFlags() {228includeClassLoaderName = false;229includeModuleVersion = false;230}231/*[ENDIF] JAVA_SPEC_VERSION >= 11*/232233/**234* Returns the full name (i.e. including package) of the class where this235* stack trace element is executing.236*237* @return the name of the class where this stack trace element is238* executing.239*/240public String getClassName() {241return (declaringClass == null) ? "<unknown class>" : declaringClass; //$NON-NLS-1$242}243244/**245* If available, returns the name of the file containing the Java code246* source which was compiled into the class where this stack trace element247* is executing.248*249* @return the name of the Java code source file which was compiled into the250* class where this stack trace element is executing. If not251* available, a <code>null</code> value is returned.252*/253public String getFileName() {254return fileName;255}256257/**258* Returns the source file line number for the class where this stack trace259* element is executing.260*261* @return the line number in the source file corresponding to where this262* stack trace element is executing.263*/264public int getLineNumber() {265/*[PR CMVC 82268] does not return the same value passed into the constructor */266return lineNumber;267}268269270/**271* Returns the name of the method where this stack trace element is272* executing.273*274* @return the method in which this stack trace element is executing.275* Returns <<code>unknown method</code>> if the name of the276* method cannot be determined.277*/278public String getMethodName() {279return (methodName == null) ? "<unknown method>" : methodName; //$NON-NLS-1$280}281282/**283* Returns a hash code value for this stack trace element.284*/285@Override286public int hashCode() {287// either both methodName and declaringClass are null, or neither are null288if (methodName == null) return 0; // all unknown methods hash the same289int hashCode = methodName.hashCode() ^ declaringClass.hashCode(); // declaringClass never null if methodName is non-null290/*[IF JAVA_SPEC_VERSION >= 11]*/291if (null != moduleName) {292hashCode ^= moduleName.hashCode();293}294if (null != moduleVersion) {295hashCode ^= moduleVersion.hashCode();296}297/*[ENDIF] JAVA_SPEC_VERSION >= 11*/298return hashCode;299}300301/**302* Returns <code>true</code> if the method name returned by303* {@link #getMethodName()} is implemented as a native method.304*305* @return true if the method is a native method306*/307public boolean isNativeMethod() {308return lineNumber == -2;309}310311/**312* Returns a string representation of this stack trace element.313*/314@Override315public String toString() {316StringBuilder buf = new StringBuilder(80);317boolean includeExtendedInfo = false;318/*[IF JAVA_SPEC_VERSION >= 11]*/319/**320* includeExtendedInfo is essentially a check to see if this StackTraceElement321* was created using a public constructor. Both includeClassLoaderName and322* includeModuleVersion are initialized to true in the public constructors,323* since these pieces of information are to be included in the stack trace.324*325* It's also possible that both of these flags are set to true natively,326* in which case we still want to include extended info when printing the327* stack trace.328*/329includeExtendedInfo = includeClassLoaderName && includeModuleVersion;330/*[ENDIF] JAVA_SPEC_VERSION >= 11*/331Util.printStackTraceElement(this, source, buf, includeExtendedInfo);332return buf.toString();333}334335}336337338