1 /*
2  * Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
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
26 package java.lang;
27
28 import jdk.internal.loader.BuiltinClassLoader;
29 import jdk.internal.misc.VM;
30 import jdk.internal.module.ModuleHashes;
31 import jdk.internal.module.ModuleReferenceImpl;
32
33 import java.lang.module.ModuleDescriptor.Version;
34 import java.lang.module.ModuleReference;
35 import java.lang.module.ResolvedModule;
36 import java.util.HashSet;
37 import java.util.Objects;
38 import java.util.Optional;
39 import java.util.Set;
40
41 /**
42  * An element in a stack trace, as returned by {@link
43  * Throwable#getStackTrace()}.  Each element represents a single stack frame.
44  * All stack frames except for the one at the top of the stack represent
45  * a method invocation.  The frame at the top of the stack represents the
46  * execution point at which the stack trace was generated.  Typically,
47  * this is the point at which the throwable corresponding to the stack trace
48  * was created.
49  *
50  * @since  1.4
51  * @author Josh Bloch
52  */

53 public final class StackTraceElement implements java.io.Serializable {
54
55     // For Throwables and StackWalker, the VM initially sets this field to a
56     // reference to the declaring Class.  The Class reference is used to
57     // construct the 'format' bitmap, and then is cleared.
58     //
59     // For STEs constructed using the public constructors, this field is not used.
60     private transient Class<?> declaringClassObject;
61
62     // Normally initialized by VM
63     private String classLoaderName;
64     private String moduleName;
65     private String moduleVersion;
66     private String declaringClass;
67     private String methodName;
68     private String fileName;
69     private int    lineNumber;
70     private byte   format = 0; // Default to show all
71
72     /**
73      * Creates a stack trace element representing the specified execution
74      * point. The {@link #getModuleName module name} and {@link
75      * #getModuleVersion module version} of the stack trace element will
76      * be {@code null}.
77      *
78      * @param declaringClass the fully qualified name of the class containing
79      *        the execution point represented by the stack trace element
80      * @param methodName the name of the method containing the execution point
81      *        represented by the stack trace element
82      * @param fileName the name of the file containing the execution point
83      *         represented by the stack trace element, or {@code nullif
84      *         this information is unavailable
85      * @param lineNumber the line number of the source line containing the
86      *         execution point represented by this stack trace element, or
87      *         a negative number if this information is unavailable. A value
88      *         of -2 indicates that the method containing the execution point
89      *         is a native method
90      * @throws NullPointerException if {@code declaringClass} or
91      *         {@code methodName} is null
92      * @since 1.5
93      * @revised 9
94      * @spec JPMS
95      */

96     public StackTraceElement(String declaringClass, String methodName,
97                              String fileName, int lineNumber) {
98         this(nullnullnull, declaringClass, methodName, fileName, lineNumber);
99     }
100
101     /**
102      * Creates a stack trace element representing the specified execution
103      * point.
104      *
105      * @param classLoaderName the class loader name if the class loader of
106      *        the class containing the execution point represented by
107      *        the stack trace is named; otherwise {@code null}
108      * @param moduleName the module name if the class containing the
109      *        execution point represented by the stack trace is in a named
110      *        module; otherwise {@code null}
111      * @param moduleVersion the module version if the class containing the
112      *        execution point represented by the stack trace is in a named
113      *        module that has a version; otherwise {@code null}
114      * @param declaringClass the fully qualified name of the class containing
115      *        the execution point represented by the stack trace element
116      * @param methodName the name of the method containing the execution point
117      *        represented by the stack trace element
118      * @param fileName the name of the file containing the execution point
119      *        represented by the stack trace element, or {@code nullif
120      *        this information is unavailable
121      * @param lineNumber the line number of the source line containing the
122      *        execution point represented by this stack trace element, or
123      *        a negative number if this information is unavailable. A value
124      *        of -2 indicates that the method containing the execution point
125      *        is a native method
126      *
127      * @throws NullPointerException if {@code declaringClass} is {@code null}
128      *         or {@code methodName} is {@code null}
129      *
130      * @since 9
131      * @spec JPMS
132      */

133     public StackTraceElement(String classLoaderName,
134                              String moduleName, String moduleVersion,
135                              String declaringClass, String methodName,
136                              String fileName, int lineNumber) {
137         this.classLoaderName = classLoaderName;
138         this.moduleName      = moduleName;
139         this.moduleVersion   = moduleVersion;
140         this.declaringClass  = Objects.requireNonNull(declaringClass, "Declaring class is null");
141         this.methodName      = Objects.requireNonNull(methodName, "Method name is null");
142         this.fileName        = fileName;
143         this.lineNumber      = lineNumber;
144     }
145
146     /*
147      * Private constructor for the factory methods to create StackTraceElement
148      * for Throwable and StackFrameInfo
149      */

150     private StackTraceElement() {}
151
152     /**
153      * Returns the name of the source file containing the execution point
154      * represented by this stack trace element.  Generally, this corresponds
155      * to the {@code SourceFile} attribute of the relevant {@code class}
156      * file (as per <i>The Java Virtual Machine Specification</i>, Section
157      * 4.7.7).  In some systems, the name may refer to some source code unit
158      * other than a file, such as an entry in source repository.
159      *
160      * @return the name of the file containing the execution point
161      *         represented by this stack trace element, or {@code nullif
162      *         this information is unavailable.
163      */

164     public String getFileName() {
165         return fileName;
166     }
167
168     /**
169      * Returns the line number of the source line containing the execution
170      * point represented by this stack trace element.  Generally, this is
171      * derived from the {@code LineNumberTable} attribute of the relevant
172      * {@code class} file (as per <i>The Java Virtual Machine
173      * Specification</i>, Section 4.7.8).
174      *
175      * @return the line number of the source line containing the execution
176      *         point represented by this stack trace element, or a negative
177      *         number if this information is unavailable.
178      */

179     public int getLineNumber() {
180         return lineNumber;
181     }
182
183     /**
184      * Returns the module name of the module containing the execution point
185      * represented by this stack trace element.
186      *
187      * @return the module name of the {@code Module} containing the execution
188      *         point represented by this stack trace element; {@code null}
189      *         if the module name is not available.
190      * @since 9
191      * @spec JPMS
192      * @see Module#getName()
193      */

194     public String getModuleName() {
195         return moduleName;
196     }
197
198     /**
199      * Returns the module version of the module containing the execution point
200      * represented by this stack trace element.
201      *
202      * @return the module version of the {@code Module} containing the execution
203      *         point represented by this stack trace element; {@code null}
204      *         if the module version is not available.
205      * @since 9
206      * @spec JPMS
207      * @see java.lang.module.ModuleDescriptor.Version
208      */

209     public String getModuleVersion() {
210         return moduleVersion;
211     }
212
213     /**
214      * Returns the name of the class loader of the class containing the
215      * execution point represented by this stack trace element.
216      *
217      * @return the name of the class loader of the class containing the execution
218      *         point represented by this stack trace element; {@code null}
219      *         if the class loader is not named.
220      *
221      * @since 9
222      * @spec JPMS
223      * @see java.lang.ClassLoader#getName()
224      */

225     public String getClassLoaderName() {
226         return classLoaderName;
227     }
228
229     /**
230      * Returns the fully qualified name of the class containing the
231      * execution point represented by this stack trace element.
232      *
233      * @return the fully qualified name of the {@code Class} containing
234      *         the execution point represented by this stack trace element.
235      */

236     public String getClassName() {
237         return declaringClass;
238     }
239
240     /**
241      * Returns the name of the method containing the execution point
242      * represented by this stack trace element.  If the execution point is
243      * contained in an instance or class initializer, this method will return
244      * the appropriate <i>special method name</i>, {@code <init>} or
245      * {@code <clinit>}, as per Section 3.9 of <i>The Java Virtual
246      * Machine Specification</i>.
247      *
248      * @return the name of the method containing the execution point
249      *         represented by this stack trace element.
250      */

251     public String getMethodName() {
252         return methodName;
253     }
254
255     /**
256      * Returns true if the method containing the execution point
257      * represented by this stack trace element is a native method.
258      *
259      * @return {@code trueif the method containing the execution point
260      *         represented by this stack trace element is a native method.
261      */

262     public boolean isNativeMethod() {
263         return lineNumber == -2;
264     }
265
266     /**
267      * Returns a string representation of this stack trace element.
268      *
269      * @apiNote The format of this string depends on the implementation, but the
270      * following examples may be regarded as typical:
271      * <ul>
272      * <li>
273      *     "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Main.java:101)}"
274      * - See the description below.
275      * </li>
276      * <li>
277      *     "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Main.java)}"
278      * - The line number is unavailable.
279      * </li>
280      * <li>
281      *     "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Unknown Source)}"
282      * - Neither the file name nor the line number is available.
283      * </li>
284      * <li>
285      *     "{@code com.foo.loader/foo@9.0/com.foo.Main.run(Native Method)}"
286      * - The method containing the execution point is a native method.
287      * </li>
288      * <li>
289      *     "{@code com.foo.loader//com.foo.bar.App.run(App.java:12)}"
290      * - The class of the execution point is defined in the unnamed module of
291      * the class loader named {@code com.foo.loader}.
292      * </li>
293      * <li>
294      *     "{@code acme@2.1/org.acme.Lib.test(Lib.java:80)}"
295      * - The class of the execution point is defined in {@code acme} module
296      * loaded by a built-in class loader such as the application class loader.
297      * </li>
298      * <li>
299      *     "{@code MyClass.mash(MyClass.java:9)}"
300      * - {@code MyClass} class is on the application class path.
301      * </li>
302      * </ul>
303      *
304      * <p> The first example shows a stack trace element consisting of
305      * three elements, each separated by {@code "/"} followed with
306      * the source file name and the line number of the source line
307      * containing the execution point.
308      *
309      * The first element "{@code com.foo.loader}" is
310      * the name of the class loader.  The second element "{@code foo@9.0}"
311      * is the module name and version.  The third element is the method
312      * containing the execution point; "{@code com.foo.Main"}" is the
313      * fully-qualified class name and "{@code run}" is the name of the method.
314      * "{@code Main.java}" is the source file name and "{@code 101}" is
315      * the line number.
316      *
317      * <p> If a class is defined in an <em>unnamed module</em>
318      * then the second element is omitted as shown in
319      * "{@code com.foo.loader//com.foo.bar.App.run(App.java:12)}".
320      *
321      * <p> If the class loader is a <a href="ClassLoader.html#builtinLoaders">
322      * built-in class loader</a> or is not named then the first element
323      * and its following {@code "/"} are omitted as shown in
324      * "{@code acme@2.1/org.acme.Lib.test(Lib.java:80)}".
325      * If the first element is omitted and the module is an unnamed module,
326      * the second element and its following {@code "/"} are also omitted
327      * as shown in "{@code MyClass.mash(MyClass.java:9)}".
328      *
329      * <p> The {@code toString} method may return two different values on two
330      * {@code StackTraceElement} instances that are
331      * {@linkplain #equals(Object) equal}, for example one created via the
332      * constructor, and one obtained from {@link java.lang.Throwable} or
333      * {@link java.lang.StackWalker.StackFrame}, where an implementation may
334      * choose to omit some element in the returned string.
335      *
336      * @revised 9
337      * @spec JPMS
338      * @see    Throwable#printStackTrace()
339      */

340     public String toString() {
341         String s = "";
342         if (!dropClassLoaderName() && classLoaderName != null &&
343                 !classLoaderName.isEmpty()) {
344             s += classLoaderName + "/";
345         }
346         if (moduleName != null && !moduleName.isEmpty()) {
347             s += moduleName;
348
349             if (!dropModuleVersion() && moduleVersion != null &&
350                     !moduleVersion.isEmpty()) {
351                 s += "@" + moduleVersion;
352             }
353         }
354         s = s.isEmpty() ? declaringClass : s + "/" + declaringClass;
355
356         return s + "." + methodName + "(" +
357              (isNativeMethod() ? "Native Method)" :
358               (fileName != null && lineNumber >= 0 ?
359                fileName + ":" + lineNumber + ")" :
360                 (fileName != null ?  ""+fileName+")" : "Unknown Source)")));
361     }
362
363     /**
364      * Returns true if the specified object is another
365      * {@code StackTraceElement} instance representing the same execution
366      * point as this instance.  Two stack trace elements {@code a} and
367      * {@code b} are equal if and only if:
368      * <pre>{@code
369      *     equals(a.getClassLoaderName(), b.getClassLoaderName()) &&
370      *     equals(a.getModuleName(), b.getModuleName()) &&
371      *     equals(a.getModuleVersion(), b.getModuleVersion()) &&
372      *     equals(a.getClassName(), b.getClassName()) &&
373      *     equals(a.getMethodName(), b.getMethodName())
374      *     equals(a.getFileName(), b.getFileName()) &&
375      *     a.getLineNumber() == b.getLineNumber()
376      *
377      * }</pre>
378      * where {@code equals} has the semantics of {@link
379      * java.util.Objects#equals(Object, Object) Objects.equals}.
380      *
381      * @param  obj the object to be compared with this stack trace element.
382      * @return true if the specified object is another
383      *         {@code StackTraceElement} instance representing the same
384      *         execution point as this instance.
385      *
386      * @revised 9
387      * @spec JPMS
388      */

389     public boolean equals(Object obj) {
390         if (obj==this)
391             return true;
392         if (!(obj instanceof StackTraceElement))
393             return false;
394         StackTraceElement e = (StackTraceElement)obj;
395         return Objects.equals(classLoaderName, e.classLoaderName) &&
396             Objects.equals(moduleName, e.moduleName) &&
397             Objects.equals(moduleVersion, e.moduleVersion) &&
398             e.declaringClass.equals(declaringClass) &&
399             e.lineNumber == lineNumber &&
400             Objects.equals(methodName, e.methodName) &&
401             Objects.equals(fileName, e.fileName);
402     }
403
404     /**
405      * Returns a hash code value for this stack trace element.
406      */

407     public int hashCode() {
408         int result = 31*declaringClass.hashCode() + methodName.hashCode();
409         result = 31*result + Objects.hashCode(classLoaderName);
410         result = 31*result + Objects.hashCode(moduleName);
411         result = 31*result + Objects.hashCode(moduleVersion);
412         result = 31*result + Objects.hashCode(fileName);
413         result = 31*result + lineNumber;
414         return result;
415     }
416
417
418     /**
419      * Called from of() methods to set the 'format' bitmap using the Class
420      * reference stored in declaringClassObject, and then clear the reference.
421      *
422      * <p>
423      * If the module is a non-upgradeable JDK module, then set
424      * JDK_NON_UPGRADEABLE_MODULE to omit its version string.
425      * <p>
426      * If the loader is one of the built-in loaders (`boot`, `platform`, or `app`)
427      * then set BUILTIN_CLASS_LOADER to omit the first element (`<loader>/`).
428      */

429     private synchronized void computeFormat() {
430         try {
431             Class<?> cls = (Class<?>) declaringClassObject;
432             ClassLoader loader = cls.getClassLoader0();
433             Module m = cls.getModule();
434             byte bits = 0;
435
436             // First element - class loader name
437             // Call package-private ClassLoader::name method
438
439             if (loader instanceof BuiltinClassLoader) {
440                 bits |= BUILTIN_CLASS_LOADER;
441             }
442
443             // Second element - module name and version
444
445             // Omit if is a JDK non-upgradeable module (recorded in the hashes
446             // in java.base)
447             if (isHashedInJavaBase(m)) {
448                 bits |= JDK_NON_UPGRADEABLE_MODULE;
449             }
450             format = bits;
451         } finally {
452             // Class reference no longer needed, clear it
453             declaringClassObject = null;
454         }
455     }
456
457     private static final byte BUILTIN_CLASS_LOADER       = 0x1;
458     private static final byte JDK_NON_UPGRADEABLE_MODULE = 0x2;
459
460     private boolean dropClassLoaderName() {
461         return (format & BUILTIN_CLASS_LOADER) == BUILTIN_CLASS_LOADER;
462     }
463
464     private boolean dropModuleVersion() {
465         return (format & JDK_NON_UPGRADEABLE_MODULE) == JDK_NON_UPGRADEABLE_MODULE;
466     }
467
468     /**
469      * Returns true if the module is hashed with java.base.
470      * <p>
471      * This method returns false when running on the exploded image
472      * since JDK modules are not hashed. They have no Version attribute
473      * and so "@<version>" part will be omitted anyway.
474      */

475     private static boolean isHashedInJavaBase(Module m) {
476         // return true if module system is not initialized as the code
477         // must be in java.base
478         if (!VM.isModuleSystemInited())
479             return true;
480
481         return ModuleLayer.boot() == m.getLayer() && HashedModules.contains(m);
482     }
483
484     /*
485      * Finds JDK non-upgradeable modules, i.e. the modules that are
486      * included in the hashes in java.base.
487      */

488     private static class HashedModules {
489         static Set<String> HASHED_MODULES = hashedModules();
490
491         static Set<String> hashedModules() {
492
493             Optional<ResolvedModule> resolvedModule = ModuleLayer.boot()
494                     .configuration()
495                     .findModule("java.base");
496             assert resolvedModule.isPresent();
497             ModuleReference mref = resolvedModule.get().reference();
498             assert mref instanceof ModuleReferenceImpl;
499             ModuleHashes hashes = ((ModuleReferenceImpl)mref).recordedHashes();
500             if (hashes != null) {
501                 Set<String> names = new HashSet<>(hashes.names());
502                 names.add("java.base");
503                 return names;
504             }
505
506             return Set.of();
507         }
508
509         static boolean contains(Module m) {
510             return HASHED_MODULES.contains(m.getName());
511         }
512     }
513
514
515     /*
516      * Returns an array of StackTraceElements of the given depth
517      * filled from the backtrace of a given Throwable.
518      */

519     static StackTraceElement[] of(Throwable x, int depth) {
520         StackTraceElement[] stackTrace = new StackTraceElement[depth];
521         for (int i = 0; i < depth; i++) {
522             stackTrace[i] = new StackTraceElement();
523         }
524
525         // VM to fill in StackTraceElement
526         initStackTraceElements(stackTrace, x);
527
528         // ensure the proper StackTraceElement initialization
529         for (StackTraceElement ste : stackTrace) {
530             ste.computeFormat();
531         }
532         return stackTrace;
533     }
534
535     /*
536      * Returns a StackTraceElement from a given StackFrameInfo.
537      */

538     static StackTraceElement of(StackFrameInfo sfi) {
539         StackTraceElement ste = new StackTraceElement();
540         initStackTraceElement(ste, sfi);
541
542         ste.computeFormat();
543         return ste;
544     }
545
546     /*
547      * Sets the given stack trace elements with the backtrace
548      * of the given Throwable.
549      */

550     private static native void initStackTraceElements(StackTraceElement[] elements,
551                                                       Throwable x);
552     /*
553      * Sets the given stack trace element with the given StackFrameInfo
554      */

555     private static native void initStackTraceElement(StackTraceElement element,
556                                                      StackFrameInfo sfi);
557
558     private static final long serialVersionUID = 6992337162326171013L;
559 }
560