5

In response to Can Java's NullPointerException be changed to report on which variable was null? thorbjorn-ravn-andersen says:

No, the debug information in the class file does not contain enough information to allow this.

My question is, why not?

Community
  • 1
  • 1
Ken Taylor
  • 160
  • 8
  • Strange, it seems to me that all the neccessary information _is_ able to be there. Namely, There are the optional `LocalVariableTable`, `LocalVariableTypeTable` (the latter since Java 5) attributes of each method (http://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html#jvms-4.7.14). – John Dvorak Jan 02 '13 at 22:23
  • If the breakpoint on NPE in your debugger you will be able to see which value is `null` – Peter Lawrey Jan 02 '13 at 23:50
  • @JanDvorak - Yep, debuggers could figure things out in a bit more detail if they thought it was worth the effort. Requires no change to the JVM. – Hot Licks Jan 03 '13 at 17:22

3 Answers3

3

The actual exception points to a particular bytecode instruction, but a language statement may expand into dozens of instructions with a half-dozen different pointers referenced. Additionally, the pointers may have been held in temporary storage (bytecode stack) for the duration of several instructions, so the association with a specific variable name is likely lost.

A fancy debugger could make a fair guess at the variable that was "at fault", but, generally speaking, being pointed to the failing statement should be sufficient (though bearing in mind that the failure may be due to a prior statement whose action was deferred).

John Dvorak
  • 26,799
  • 13
  • 69
  • 83
Hot Licks
  • 47,103
  • 17
  • 93
  • 151
  • Technically, "bytecode" refers to all the instructions together (or to the instruction set itself). – John Dvorak Jan 02 '13 at 21:49
  • Might I suggest then that the reason that the stack trace cannot report that the cause of a NPE was related to a particular dereferencing is that the overhead required to do so was not deemed to be warranted given the other ways of obtaining this information (reproducing in debugger and by inspection)? – Ken Taylor Jan 03 '13 at 17:10
  • @KenTaylor - I think it's more that the effort required on the part of the developers, at the time that the JDK was first being invented, was greater than they wanted to expend, and since then there has never been enough need to overcome the inherent resistance to changing the JDK spec. (Frankly, this issue is hardly worth the virtual ink -- I've rarely had difficulty figuring out the source of the null, once I got it down to a specific statement.) – Hot Licks Jan 03 '13 at 17:19
  • "effort required ... greater than they wanted" is what I meant by "overhead required ... not deemed to be warranted". I find this issue worthwhile discussing because I often find that I cannot reproduce a live problem for which I only have a stack trace and none of the variables dereferenced should be null; I don't want to check for null at the point of dereferencing - I want to trace back to where the null was introduced and keep it from happening. And if I know exactly what was null, that narrows the search. – Ken Taylor Jan 03 '13 at 19:54
  • @KenTaylor - The problem is, even if you know WHICH variable was null, you have no real clue as to WHY, and that's usually the much more difficult problem. It's actually fairly rare to have a situation where more than one reference in a given statement can be null, but it's exceedingly common for the one null reference to have been set null in some distant (in time and location) piece of code. And there's no fix for that problem. – Hot Licks Jan 03 '13 at 21:19
  • I disagree that it is rare to have more than one reference in a line that can be (given that none of them should be) null. I run into it with most of the NPE's I encounter in a stack trace. I do agree that it is common that the null reference is distantly set and difficult to locate but that is why I would find it beneficial to have only one variable to track down. – Ken Taylor Jan 04 '13 at 00:45
  • @KenTaylor - In most cases one can examine the pointers flowing into the statement and find references to them in previous statements. If a local pointer was referenced in a previous statement that dominates the failing statement then one can be confident that the pointer is good. It maybe gets a little iffier when the pointer is from another object, but only if there is some likelihood of concurrent update. It is unfortunate that the available exception information does not include the specific bytecode address -- I'm reasonably sure that info is available internally, but it's not exposed. – Hot Licks Jan 04 '13 at 01:08
3

It may not have been a variable at all: it may have been a temporary result, e.g. the result of a method call. By the time the NPE occurs it is just an anonymous stack slot.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • Note that "results of a method call" do have specific classes that the debugger _should_ be able to know. – John Dvorak Jan 02 '13 at 21:54
  • @JanDvorak Of course, but the question is about stack traces, not debuggers. – user207421 Jan 02 '13 at 22:24
  • @JanDvorak Are all those questions really directed to me? You seem to be just arguing with yourself. The relevant facts are that class files don't necessarily contain local variable names, and that variable names in any case aren't the only possibility, and these are sufficient to answer the question. – user207421 Jan 03 '13 at 00:16
  • @EJP: The NPE may not have been the result of dereferencing a variable. But let's say it was. The stack trace has information to report the method and line number but cannot hang onto the name of the variable (which JD speculates above is information that is available)? – Ken Taylor Jan 03 '13 at 16:43
0

Because line number in the code is sufficient enough to trace it.