Useful message about NullPointerException

Peter Levart peter.levart at
Wed Jan 28 15:59:38 UTC 2015

On 01/28/2015 03:30 AM, David Holmes wrote:
>> 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:
> Once past suggestion has been to include the ByteCode Index (BCI) as 
> part of the exception stacktrace information:
> David 


I checked per-method CharacterRangeTable that gets emitted by javac 
-Xjcov option, and unfortunately it is of limited use. The 
CharacterRangeTable contains mappings from byte code index ranges 
(start-bci, end-bci) -> character ranges (start-line, start-column, 
end-line, end-column) of adequate code in source file. The ranges I have 
observed have 2 granularities: "statement" and "block". For example, the 
following program:

public class CharRangeTest {

     String str() {
         return "ABC";

     public static void main(String[] args) {
         int i = new CharRangeTest().str().substring(1).length();

Compiles to the following bytecodes for main method:

   public static void main(java.lang.String[]);
     descriptor: ([Ljava/lang/String;)V
       stack=2, locals=2, args_size=1
          0: new           #3                  // class CharRangeTest
          3: dup
          4: invokespecial #4                  // Method "<init>":()V
          7: invokevirtual #5                  // Method 
         10: iconst_1
         11: invokevirtual #6                  // Method 
         14: invokevirtual #7                  // Method 
         17: istore_1
         18: getstatic     #8                  // Field 
         21: iload_1
         22: invokevirtual #9                  // Method 
         25: return
         line 11: 0
         line 12: 18
         line 13: 25
              0, 17,   2c09,   2c41,    1        //  0, 17, 11:09,   
11:65, statement
             18, 24,   3009,   301f,    1        // 18, 24, 12:09,   
12:31, statement
              0, 25,   282c,   3406,    2        //  0, 25, 10:44,   
13:06, block

CharacterRangeTable says that bytecodes at indexes 0 to 17 map to source 
code from (line 11, column 9) to (line 11, column 64) and that this 
range is a "statement". Unfortunately, the assignment to i of the result 
of the whole chain of invocations is a single Java "statement":

int i = new CharRangeTest().str().substring(1).length();

So if NPE happens anywhere in this statement, we could only pin-point 
the statement and not a particular null dereference. The only time this 
would give us some additional info is when there are more statements in 
the line, like:

     x.doSomething(); y.doSomeMore();

...but such code formatting is very rare if non-existent.

If adding column number to StackTraceElement (JDK-8020204) is currently 
not an easy thing to do, since it would require javac changes, adding 
byte code index (JDK-4185378 ) is trivial:

With this patch, I get the following style of stack-traces:

Exception in thread "main" /tmp/x (No 
such file or directory)
         at Method)
         at Test.dump[9](
         at Test.main[3](

The numbers in square brackets are byte code indexes that pin-point the 
location in byte code. With the help of javap, one can use this info to 
find out the cause of exception even without having access to sources.

Regards, Peter

More information about the core-libs-dev mailing list