[15] RFR: 8248476: No helpful NullPointerException message after calling fillInStackTrace
Mandy Chung
mandy.chung at oracle.com
Mon Jul 13 19:53:32 UTC 2020
Hi Goetz,
I digged up some history of setStackTrace.
> Well, all the scenario are quite artificial:
> - why would you call fillInStackTrace on an exception thrown by the VM?
> - why would you call setStackTrace at all?
FYI on the history on `setStackTrace` - this API is designed for the
client side to fill in the stack trace for example concatening the
server-side stack trace with appropriate client-side stack trace (see
JDK-4010355).
As described in JEP 358, NPEs that are explicitly created and/or
explicitly thrown by programs running on the JVM are not subject to the
bytecode analysis. So it's reasonable to include the case that NPE
whose stack trace is explicitly replaced via `fillInStackTrace` or
`setStackTrace` are not subject to the bytecode analysis (rather than
only `fillInStackTrace`).
>> To me that makes
>> far more sense than having msg2 continue to report the extended info for
>> the original stacktrace when it now has a new stacktrace.
>>
>> I'm really not seeing why calling fillInstackTrace() a second time
>> should be treated any differently to calling setStackTrace(). They
>> should be handled consistently IMO.
I agree with David on this point. `fillInStackTrace` and
`setStackTrace` both override this throwable with a different stack
trace and I don't see why we want them to behave differently.
> But then you treat setStackTrace() differently from setStackTrace()
> with other exceptions.
> The reason to treat fillInStackTrace differently is that we lost information
> needed to compute it. This is not the case with setStackTrace().
This is because backtrace is not reset to null which is just the current
implementation. A simple way is to override NPE::setStackTrace to
indicate that this NPE instance is not subject to bytecode analysis.
> A different solution, the one I would have proposed if I had not
> considered previous comments from reviews, would be to just
> compute the message in the runtime in the call of fillInStackTrace
> before the old stack trace is lost and assign it to the message field.
> This way it would behave similar to all other exceptions. The message
> would just be there ... just that it's computed lazily.
> The cost of the algorithm wouldn't harm that much as other costly
> algorithms (walking the stack) are performed at this point, too.
>
I expect most common cases calling fillInStackTrace and setStackTrace
are on explicitly created NPEs which are not subject to bytecode
analysis. While it should be rare to see NPE with an extended message
but its stack trace is replaced, such NPE message + stack trace would be
quite confusing.
OTOH, it's okay with me if you want to replace
NPE::numStackTracesFilledIn with a volatile NPE::message field instead
such that it's assigned to the result returned from
getExtendedNPEMessage() and reset to an empty string if the stack trace
is overridden.
Mandy
More information about the hotspot-runtime-dev
mailing list