mgroovy created GROOVY-10258:
--------------------------------

             Summary: NPE: Pinpoint Exact Location in Call Chain
                 Key: GROOVY-10258
                 URL: https://issues.apache.org/jira/browse/GROOVY-10258
             Project: Groovy
          Issue Type: Bug
            Reporter: mgroovy


Groovy should output the exact location where a NullPointerException occurred 
inside a call chain in the NPE message, if possible pretty printed.

The JVM has been improved in this regard since OpenJDK 14:
https://openjdk.java.net/jeps/358
https://www.baeldung.com/java-14-nullpointerexception
https://bugs.openjdk.java.net/browse/JDK-8233014

The messages produced alas look pretty ugly for @CompileStatic Groovy (see 
below), due to its predominant use of properties instead of fields, and the 
original goal of JEP 358 to print the complete call chain (access path) seems 
to have been dropped, so it is not particularily helpful in some situations 
(see examples below).

In Groovy 3.0.9 under OpenJDK 16:

{code}
@Newify(pattern=/[A-Z][A-Za-z0-9_]*/)
//@CompileStatic
class HelpfulNullPointerExceptionTest {

    static class X {
        X x; String s
        X(X x, String s = null) { this.x = x; this.s = s }
        @Override String toString() { "X($s,$x)" }
    }

    @Test
    void nullPointerInCallChain() {
        final x = X(X(X(X(null,"X-Men"))))
        println "x.x.x.x=$x.x.x.x"
        x.x.x = null
        /*
            * OpenJDK 16 (Eclipse jdk-16.0.2.7-hotspot) (Note: 
-XX:+ShowCodeDetailsInExceptionMessages is now always on by default)
            ** @CompileDynamic: java.lang.NullPointerException: Cannot get 
property 'x' on null object
            ** @CompileStatic: java.lang.NullPointerException: Cannot invoke 
"simple.groovy.HelpfulNullPointerExceptionTest$X.getX()" because the return 
value of "simple.groovy.HelpfulNullPointerExceptionTest$X.getX()" is null
            ** Would hope for something like (or its pretty-printed 
equivalent): java.lang.NullPointerException: Cannot get property 'x.x.x.x' on 
null object
        */
        println "x.x.x.x=$x.x.x.x"
    }

    @Canonical static class A { String a }
    @Canonical static class B { A a }
    @Canonical static class C { B b }
    @Canonical static class D { C c }

    @Test
    void nullPointerInCallChain2() {
        final x = D(C(B(A("aha!"))))
        println "x.c.b.a=$x.c.b.a"
        /*
            * OpenJDK 16 (Eclipse jdk-16.0.2.7-hotspot)
            ** @CompileDynamic: java.lang.NullPointerException: Cannot get 
property 'b' on null object
            ** @CompileStatic: java.lang.NullPointerException: Cannot invoke 
"simple.groovy.HelpfulNullPointerExceptionTest$C.getB()" because the return 
value of "simple.groovy.HelpfulNullPointerExceptionTest$D.getC()" is null
            ** Would hope for something like (or its pretty-printed 
equivalent): java.lang.NullPointerException: Cannot get property 'x.c.b.a' on 
null object
        */
        x.c = null
        println "x.c.b.a=$x.c.b.a"
    }
}
{code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to