< prev index next >

test/hotspot/jtreg/runtime/exceptionMsgs/NullPointerException/NullPointerExceptionTest.java

Print this page
rev 59858 : 8248476: No helpful NullPointerException message after calling fillInStackTrace
Summary: reported by christoph.dreis@freenet.de
Reviewed-by:
rev 58801 : 8242311: use reproducible random in hotspot runtime tests
Reviewed-by: iklam, mseledtsov
rev 56645 : 8218628: Add detailed message to NullPointerException describing what is null.
Summary: This is the implementation of JEP 358: Helpful NullPointerExceptions.
Reviewed-by: coleenp, clanger, rschmelter, rriggs, forax, mr

@@ -26,11 +26,11 @@
  * @test
  * @key randomness
  * @summary Test extended NullPointerException message for
  *   classfiles generated with debug information. In this case the name
  *   of the variable containing the array is printed.
- * @bug 8218628
+ * @bug 8218628 8248476
  * @modules java.base/java.lang:open
  *          java.base/jdk.internal.org.objectweb.asm
  * @library /test/lib
  * @compile -g NullPointerExceptionTest.java
  * @run main/othervm -XX:MaxJavaStackTraceDepth=1 -XX:+ShowCodeDetailsInExceptionMessages NullPointerExceptionTest hasDebugInfo

@@ -39,11 +39,11 @@
  * @test
  * @key randomness
  * @summary Test extended NullPointerException message for class
  *   files generated without debugging information. The message lists
  *   detailed information about the entity that is null.
- * @bug 8218628
+ * @bug 8218628 8248476
  * @modules java.base/java.lang:open
  *          java.base/jdk.internal.org.objectweb.asm
  * @library /test/lib
  * @compile NullPointerExceptionTest.java
  * @run main/othervm -XX:MaxJavaStackTraceDepth=1 -XX:+ShowCodeDetailsInExceptionMessages NullPointerExceptionTest

@@ -1279,12 +1279,80 @@
         // If allocated with new, the message should not be generated.
         Asserts.assertNull(new NullPointerException().getMessage());
         String msg = new String("A pointless message");
         Asserts.assertTrue(new NullPointerException(msg).getMessage() == msg);
 
+        // If the stack trace was set by the user, the message should not be
+        // created.
+        // This holds for explicitly crated NPEs, but also for implicilty
+        // thrown ones.
+        System.out.println(new NullPointerException().fillInStackTrace().getMessage());
+        System.out.println(new NullPointerException(msg).fillInStackTrace().getMessage());
+
+        Asserts.assertNull(new NullPointerException().fillInStackTrace().getMessage());
+        Asserts.assertTrue(new NullPointerException(msg).fillInStackTrace().getMessage() == msg);
+
+        NullPointerException ex = new NullPointerException();
+        Throwable t = ex.fillInStackTrace();
+
+        Asserts.assertNull(t.getMessage());
+
+        ex = new NullPointerException(msg);
+        t = ex.fillInStackTrace();
+        Asserts.assertTrue(t.getMessage() == msg);
+
+        F f = null;
+        try {
+            f.i = 17;
+        } catch (NullPointerException e) {
+            checkMessage(e, "f.i = 17;", e.getMessage(),
+                         "Cannot assign field \"i\" because " +
+                         (hasDebugInfo ? "\"f\"" : "\"<local4>\"") + " is null");
+            t = e.fillInStackTrace();
+        }
+        checkMessage(t, "e.fillInStackTrace()", t.getMessage(), null);
+
+        // Make sure a new exception thrown when calling fillInStackTrace()
+        // gets the correct message.
+        ex = null;
+        try {
+            ex.fillInStackTrace();
+        } catch (NullPointerException e) {
+            checkMessage(e, "ex.fillInStackTrace()", e.getMessage(),
+                         "Cannot invoke \"java.lang.NullPointerException.fillInStackTrace()\" because " +
+                         (hasDebugInfo ? "\"ex\"" : "\"<local2>\"") + " is null");
+        }
+
+        // setStackTrace does not affect computing the message.
+        // Message and stack trace won't match, though.
+        F f1 = null;
+        F f2 = null;
+        NullPointerException e1 = null;
+        NullPointerException e2 = null;
+        try {
+            f1.i = 18;
+        } catch (NullPointerException e) {
+            checkMessage(e, "f1.i = 18;", e.getMessage(),
+                         "Cannot assign field \"i\" because " +
+                         (hasDebugInfo ? "\"f1\"" : "\"<local5>\"") + " is null");
+            e1 = e;
+        }
+        try {
+            f2.i = 19;
+        } catch (NullPointerException e) {
+            checkMessage(e, "f2.i = 19;", e.getMessage(),
+                         "Cannot assign field \"i\" because " +
+                         (hasDebugInfo ? "\"f2\"" : "\"<local6>\"") + " is null");
+            e2 = e;
+        }
+        e1.setStackTrace(e2.getStackTrace());
+        checkMessage(e1, "f1.i = 18;", e1.getMessage(),
+                     "Cannot assign field \"i\" because " +
+                     (hasDebugInfo ? "\"f1\"" : "\"<local5>\"") + " is null");
+
         // If created via reflection, the message should not be generated.
-        Exception ex = NullPointerException.class.getDeclaredConstructor().newInstance();
+        ex = NullPointerException.class.getDeclaredConstructor().newInstance();
         Asserts.assertNull(ex.getMessage());
     }
 
     public void testNative() throws Exception {
         // If NPE is thrown in a native method, the message should
< prev index next >