jdk/src/java.base/share/classes/java/lang/StackTraceElement.java
changeset 36511 9d0388c6b336
parent 25859 3317bb8137f4
child 37325 22145b2d3616
--- a/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java	Tue Mar 15 13:48:26 2016 -0700
+++ b/jdk/src/java.base/share/classes/java/lang/StackTraceElement.java	Thu Mar 17 19:04:16 2016 +0000
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2000, 2015, 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
@@ -41,6 +41,8 @@
  */
 public final class StackTraceElement implements java.io.Serializable {
     // Normally initialized by VM (public constructor added in 1.5)
+    private String moduleName;
+    private String moduleVersion;
     private String declaringClass;
     private String methodName;
     private String fileName;
@@ -48,7 +50,9 @@
 
     /**
      * Creates a stack trace element representing the specified execution
-     * point.
+     * point. The {@link #getModuleName module name} and {@link
+     * #getModuleVersion module version} of the stack trace element will
+     * be {@code null}.
      *
      * @param declaringClass the fully qualified name of the class containing
      *        the execution point represented by the stack trace element
@@ -68,6 +72,40 @@
      */
     public StackTraceElement(String declaringClass, String methodName,
                              String fileName, int lineNumber) {
+        this(null, null, declaringClass, methodName, fileName, lineNumber);
+    }
+
+    /**
+     * Creates a stack trace element representing the specified execution
+     * point.
+     *
+     * @param moduleName the module name if the class containing the
+     *        execution point represented by the stack trace is in a named
+     *        module; can be {@code null}
+     * @param moduleVersion the module version if the class containing the
+     *        execution point represented by the stack trace is in a named
+     *        module that has a version; can be {@code null}
+     * @param declaringClass the fully qualified name of the class containing
+     *        the execution point represented by the stack trace element
+     * @param methodName the name of the method containing the execution point
+     *        represented by the stack trace element
+     * @param fileName the name of the file containing the execution point
+     *        represented by the stack trace element, or {@code null} if
+     *        this information is unavailable
+     * @param lineNumber the line number of the source line containing the
+     *        execution point represented by this stack trace element, or
+     *        a negative number if this information is unavailable. A value
+     *        of -2 indicates that the method containing the execution point
+     *        is a native method
+     * @throws NullPointerException if {@code declaringClass} is {@code null}
+     *         or {@code methodName} is {@code null}
+     * @since 9
+     */
+    public StackTraceElement(String moduleName, String moduleVersion,
+                             String declaringClass, String methodName,
+                             String fileName, int lineNumber) {
+        this.moduleName     = moduleName;
+        this.moduleVersion  = moduleVersion;
         this.declaringClass = Objects.requireNonNull(declaringClass, "Declaring class is null");
         this.methodName     = Objects.requireNonNull(methodName, "Method name is null");
         this.fileName       = fileName;
@@ -106,6 +144,34 @@
     }
 
     /**
+     * Returns the module name of the module containing the execution point
+     * represented by this stack trace element.
+     *
+     * @return the module name of the {@code Module} containing the execution
+     *         point represented by this stack trace element; {@code null}
+     *         if the module name is not available.
+     * @since 9
+     * @see java.lang.reflect.Module#getName()
+     */
+    public String getModuleName() {
+        return moduleName;
+    }
+
+    /**
+     * Returns the module version of the module containing the execution point
+     * represented by this stack trace element.
+     *
+     * @return the module version of the {@code Module} containing the execution
+     *         point represented by this stack trace element; {@code null}
+     *         if the module version is not available.
+     * @since 9
+     * @see java.lang.module.ModuleDescriptor.Version
+     */
+    public String getModuleVersion() {
+        return moduleVersion;
+    }
+
+    /**
      * Returns the fully qualified name of the class containing the
      * execution point represented by this stack trace element.
      *
@@ -148,32 +214,42 @@
      * examples may be regarded as typical:
      * <ul>
      * <li>
-     *   {@code "MyClass.mash(MyClass.java:9)"} - Here, {@code "MyClass"}
-     *   is the <i>fully-qualified name</i> of the class containing the
-     *   execution point represented by this stack trace element,
+     *   {@code "MyClass.mash(my.module@9.0/MyClass.java:101)"} - Here,
+     *   {@code "MyClass"} is the <i>fully-qualified name</i> of the class
+     *   containing the execution point represented by this stack trace element,
      *   {@code "mash"} is the name of the method containing the execution
-     *   point, {@code "MyClass.java"} is the source file containing the
-     *   execution point, and {@code "9"} is the line number of the source
+     *   point, {@code "my.module"} is the module name, {@code "9.0"} is the
+     *   module version, and {@code "101"} is the line number of the source
      *   line containing the execution point.
      * <li>
-     *   {@code "MyClass.mash(MyClass.java)"} - As above, but the line
-     *   number is unavailable.
+     *   {@code "MyClass.mash(my.module@9.0/MyClass.java)"} - As above, but the
+     *   line number is unavailable.
+     * <li>
+     *   {@code "MyClass.mash(my.module@9.0/Unknown Source)"} - As above, but
+     *   neither the file name nor the line  number are available.
      * <li>
-     *   {@code "MyClass.mash(Unknown Source)"} - As above, but neither
-     *   the file name nor the line  number are available.
-     * <li>
-     *   {@code "MyClass.mash(Native Method)"} - As above, but neither
-     *   the file name nor the line  number are available, and the method
-     *   containing the execution point is known to be a native method.
+     *   {@code "MyClass.mash(my.module@9.0/Native Method)"} - As above, but
+     *   neither the file name nor the line  number are available, and the
+     *   method containing the execution point is known to be a native method.
      * </ul>
+     * If the execution point is not in a named module, {@code "my.module@9.0/"}
+     * will be omitted from the above.
+     *
      * @see    Throwable#printStackTrace()
      */
     public String toString() {
-        return getClassName() + "." + methodName +
-            (isNativeMethod() ? "(Native Method)" :
-             (fileName != null && lineNumber >= 0 ?
-              "(" + fileName + ":" + lineNumber + ")" :
-              (fileName != null ?  "("+fileName+")" : "(Unknown Source)")));
+        String mid = "";
+        if (moduleName != null) {
+            mid = moduleName;
+            if (moduleVersion != null)
+                mid += "@" + moduleVersion;
+            mid += "/";
+        }
+        return getClassName() + "." + methodName + "(" + mid +
+             (isNativeMethod() ? "Native Method)" :
+              (fileName != null && lineNumber >= 0 ?
+               fileName + ":" + lineNumber + ")" :
+                (fileName != null ?  ""+fileName+")" : "Unknown Source)")));
     }
 
     /**
@@ -184,6 +260,8 @@
      * <pre>{@code
      *     equals(a.getFileName(), b.getFileName()) &&
      *     a.getLineNumber() == b.getLineNumber()) &&
+     *     equals(a.getModuleName(), b.getModuleName()) &&
+     *     equals(a.getModuleVersion(), b.getModuleVersion()) &&
      *     equals(a.getClassName(), b.getClassName()) &&
      *     equals(a.getMethodName(), b.getMethodName())
      * }</pre>
@@ -202,6 +280,8 @@
             return false;
         StackTraceElement e = (StackTraceElement)obj;
         return e.declaringClass.equals(declaringClass) &&
+            Objects.equals(moduleName, e.moduleName) &&
+            Objects.equals(moduleVersion, e.moduleVersion) &&
             e.lineNumber == lineNumber &&
             Objects.equals(methodName, e.methodName) &&
             Objects.equals(fileName, e.fileName);
@@ -212,6 +292,8 @@
      */
     public int hashCode() {
         int result = 31*declaringClass.hashCode() + methodName.hashCode();
+        result = 31*result + Objects.hashCode(moduleName);
+        result = 31*result + Objects.hashCode(moduleVersion);
         result = 31*result + Objects.hashCode(fileName);
         result = 31*result + lineNumber;
         return result;