JDK-8248476 : No helpful NullPointerException message after calling fillInStackTrace.
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 14
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2020-06-29
  • Updated: 2020-07-24
  • Resolved: 2020-07-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 15 JDK 16
15 b33Fixed 16Fixed
Related Reports
Relates :  
Description
If fillInStackTrace is called on the exception, the original stack 
trace is lost. The helpful NPE algorithm can no more compute 
the proper message. Also, the check for messages created in 
user code fails.  Thus, we must check for fillInStackTrace and 
suppress the message if it was called.

This problem was reported and analyzed by Christoph Dreis:
http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2020-June/040450.html

His example of the wrong message:

public class Main {
	public static void main(String[] args) {
		NullPointerException ex = new NullPointerException();
		Throwable throwable = ex.fillInStackTrace();
		System.out.println(throwable);
	}
}

He sees the following output:

java.lang.NullPointerException: Cannot invoke "java.lang.NullPointerException.fillInStackTrace()" because "ex" is null

which is wrong. As the exception is created explicitly via new, it should not
and can not get a proper message by this algorithm.

*Fix*

Various approaches were discussed.

Finally we decided to fix this in NullPointerException.java. 
NullPointerException now overwrites Throwable::fillInStackTrace() and 
precomputes the message before the original backtrace is overwritten.
The message is stored in a private field, and returned by getMessage().

This allowed a little enhancement: If getMessage is called repeatedly,
the message is no more recomputed on each call. This also guarantees
that each getMessage call returns the very same String object.
Comments
URL: https://hg.openjdk.java.net/jdk/jdk15/rev/96bb686a6cc2 User: goetz Date: 2020-07-15 17:35:33 +0000
15-07-2020

ILW = MMM = P3
30-06-2020

Review & webrev: http://mail.openjdk.java.net/pipermail/hotspot-runtime-dev/2020-June/040459.html http://cr.openjdk.java.net/~goetz/wr20/8248476-NPE_fillInStackTrace-jdk15/
29-06-2020