RFR(L): 8218628: Add detailed message to NullPointerException describing what is null.

Lindenmaier, Goetz goetz.lindenmaier at sap.com
Fri Mar 15 13:11:39 UTC 2019

Hi Maurizio,

thanks for sharing your patch!  This is about what I thought about
so far, just that it's working already :)

It prints the information of the failing bytecode.  Adding the dataflow
analysis, the other information could be printed as well.

The major problem I see is here:
+            File f = new File(location.getFile(),
+                    clazz.getCanonicalName().replaceAll("\\.", "/") + ".class");
+            ClassReader cr = new ClassReader(new FileInputStream(f));
+            ClassNode classNode = new ClassNode();
+            cr.accept(classNode, 0);

As I understand, this reads the Bytecode from the classfile.
The bytecode in the classfile must not match that executed
by the VM, i.e, the pc you get from the stackWalker will not
reference the bytecode that caused the NPE.

Other issues have been discussed in the mail thread before.
Good that you point this out, I'll add it to the JEP.

Best regards,

... Sorry, I missed the "reply all" on my first reply.

> -----Original Message-----
> From: Maurizio Cimadamore <maurizio.cimadamore at oracle.com>
> Sent: Freitag, 15. März 2019 12:33
> To: Lindenmaier, Goetz <goetz.lindenmaier at sap.com>; Mandy Chung
> <mandy.chung at oracle.com>; Roger Riggs <Roger.Riggs at oracle.com>
> Cc: Java Core Libs <core-libs-dev at openjdk.java.net>; hotspot-runtime-
> dev at openjdk.java.net
> Subject: Re: RFR(L): 8218628: Add detailed message to NullPointerException
> describing what is null.
> Hi Goetz,
> please find the attached ASM-based patch. It is just a PoC, as such it
> does not provide as fine-grained messages as the one discussed in the
> RFE/JEP, but can be enhanced to cover custom debugging attribute, I believe.
> When running this:
> Object o = null;
> o.toString();
> you get:
> Exception in thread "main" java.lang.NullPointerException: attempt to
> dereference 'null' when calling method 'toString'
>      at org.oracle.npe.NPEHandler.main(NPEHandler.java:103)
> While when running this:
> Foo foo = null;
> int y = foo.x;
> You get this:
> Exception in thread "main" java.lang.NullPointerException: attempt to
> dereference 'null' when accessing field 'x'
>      at org.oracle.npe.NPEHandler.main(NPEHandler.java:105)
> One problem I had is that ASM provides no way to get the instruction
> given a program counter - which means we have to scan all the bytecodes
> and update the sizes as we go along, and, ASM unfortunately doesn’t
> expose opcode sizes either. A more robust solution would be to have a
> big switch which returned the opcode size of any given opcode. Also,
> accessing to StackWalker API on exception creation might not be
> desirable in terms of performances, so this might be one of these area
> where some VM help could be beneficial. Another problem is that we
> cannot distinguish between user-generated exceptions (e.g. `throw new
> NullPointerException`) and genuine NPE issued by the VM.
> But I guess the upshot is that it works to leave all the gory detail of
> bytecode grovelling to a bytecode API - if the logic is applied lazily,
> then the impact on performances should be minimal, and the solution more
> maintainable longer term.
> Cheers
> Maurizio
> On 15/03/2019 07:59, Lindenmaier, Goetz wrote:
> > Yes, it would be nice if you shared that.

More information about the core-libs-dev mailing list