< prev index next >
src/java.base/share/classes/java/lang/NullPointerException.java
Print this page
rev 59899 : 8248476: No helpful NullPointerException message after calling fillInStackTrace
Summary: reported by christoph.dreis@freenet.de
Reviewed-by:
@@ -68,10 +68,31 @@
*/
public NullPointerException(String s) {
super(s);
}
+ private static final String mustComputeExtendedNPEMessage = "1";
+ private static final String noExtendedNPEMessage = "2";
+ private volatile transient String extendedMessage;
+
+ /**
+ * {@inheritDoc}
+ */
+ public synchronized Throwable fillInStackTrace() {
+ // After the stack trace is changed the extended NPE algorithm
+ // will compute a wrong message. So compute it beforehand.
+ if (extendedMessage == null) {
+ // The first call. Don't compute the message, we'll
+ // do it lazily.
+ extendedMessage = mustComputeExtendedNPEMessage;
+ } else if (extendedMessage == mustComputeExtendedNPEMessage) {
+ // The second call.
+ extendedMessage = getExtendedNPEMessage();
+ }
+ return super.fillInStackTrace();
+ }
+
/**
* Returns the detail message string of this throwable.
*
* <p> If a non-null message was supplied in a constructor it is
* returned. Otherwise, an implementation specific message or
@@ -87,17 +108,32 @@
* @return the detail message string, which may be {@code null}.
*/
public String getMessage() {
String message = super.getMessage();
if (message == null) {
- return getExtendedNPEMessage();
+ synchronized(this) {
+ if (extendedMessage == mustComputeExtendedNPEMessage) {
+ // Only the original stack trace was filled in. Message will
+ // compute correctly.
+ extendedMessage = getExtendedNPEMessage();
+ }
+ if (extendedMessage != noExtendedNPEMessage) {
+ return extendedMessage;
+ }
+ }
}
return message;
}
/**
* Get an extended exception message. This returns a string describing
- * the location and cause of the exception. It returns null for
+ * the location and cause of the exception. It returns noExtendedNPEMessage for
* exceptions where this is not applicable.
*/
- private native String getExtendedNPEMessage();
+ private String getExtendedNPEMessage() {
+ String msg = getExtendedNPEMessage0();
+ if (msg == null) return noExtendedNPEMessage;
+ return msg;
+ }
+
+ private native String getExtendedNPEMessage0();
}
< prev index next >