Useful message about NullPointerException

David Holmes david.holmes at oracle.com
Wed Jan 28 02:30:09 UTC 2015


Adding back in hotspot-dev to this reply

There have been previous RFEs for this dating back to 2006 - most closed 
as duplicates and the main one eventually closed as "will not fix" 
simply due to it being a low priority RFE for 8 years.

Also see:

https://bugs.openjdk.java.net/browse/JDK-6717558

On 28/01/2015 2:01 AM, Peter Levart wrote:
> On 01/27/2015 03:34 PM, kedar mhaswade wrote:
>> When the JVM executes instructions like getfield
>> <http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-6.html#jvms-6.5.getfield>,
>>
>> getstatic, invokevirtual etc. with *objref* on the operand stack and if
>> *objref* is null, an NPE is thrown. It appears that the JVM could tell us
>> more about which *objref* was null at run-time. Candidate for an RFE?
>
> In general it is hard to deduce the meaningfull source of null *objref*
> on the operand stack by analyzing the surrounding bytecodes. It could be
> a result of complex logic executed by bytecodes. Imagine the following:
>
> int length(boolean first, String s1, String s2) {
>      return (first ? s1 : s2).length();
> }
>
> ...the analysis would have to trace the live execution so that it could
> be rolled-back to the meaningful source of null *objref*.

Exactly right - all the VM knows at that exact point is that the thing 
on the stack is an object reference - if its value is null that doesn't 
tell you where that came from. You have to look around to see what 
pushed that objRef onto the stack. Might be doable from the interpreter, 
but from compiled code?

> All VM might semi-realistically do is report the action VM was trying to
> perform when it dereferenced a null *objref*. Like
> "NullPointerException: while invoking method Xxxx.yyyy on a null
> target", or "NullPointerException: while de-referencing instance field
> Xxxx.yyyy of a null reference"
>
> But what does this help if you don't have access to sources? Might be a
> hint, but not much.

As I said there may be some context to assist with how the null was 
introduced, but in general it isn't something that is readily apparent - 
especially in compiled code.

> If you have access to sources, then perhaps an easier solution would be
> for stack traces to include column number in addition to line number of
> location in source that resulted in bytecodes that include the one that
> triggered the NPE.
>
> There is already a RFE for that:
>
>      https://bugs.openjdk.java.net/browse/JDK-8020204

Once past suggestion has been to include the ByteCode Index (BCI) as 
part of the exception stacktrace information:

https://bugs.openjdk.java.net/browse/JDK-4185378

David
-----

> It seems that javac part is already there. The VM part and public API
> part (StackTraceElement) is not, though.
>
> Regards, Peter
>
>>
>> That aside, (and Chris's trick is nice), but if you have no access to the
>> source for the offending code, life is hard in general, isn't it? Because
>> if you can't have control over the source, making that source run on a
>> platform where such an RFE would be perhaps fixed (a future release of
>> the
>> JDK) would be even harder, no?
>>
>> On Tue, Jan 27, 2015 at 5:14 AM, Florian Weimer <fweimer at redhat.com>
>> wrote:
>>
>>> On 01/21/2015 01:45 PM, pike wrote:
>>>> We frequently see NullPointerException in our logs. It's really a big
>>>> headache when we see a NullPointerException and it is encapsulated in
>>>> another exception as we don't know which object is null and it is
>>> throwing
>>>> an Exception. Is there any way we can get to know the object type or
>>>> the
>>>> object variable name where the object is null and it is throwing a
>>>> NullPointerException?
>>> The line number gives you the position in the source code, and from
>>> that, you can usually figure out the static type.  If this is not
>>> helpful in your case, you need to say why (no debugging information?
>>> multiple candidates per line?).
>>>
>>> The dynamic type is a different matter though, because null has no
>>> specific type at run time.  It may be possible to provide type
>>> information in theory, at a cost, but this would best be prototyped
>>> through byte code rewriting.  Nullable annotations would also help to
>>> pin-point location of the first leak, and you could record that
>>> (including a stack trace) if you want something really fancy.  Whether
>>> it is helpful for legacy code, I don't know.  There should be some
>>> research projects out there covering this area.
>>>
>>> --
>>> Florian Weimer / Red Hat Product Security
>>>
>



More information about the core-libs-dev mailing list