Hi guys,
I don't encounter a lot of NPE in my code and have been using a lot of
@CompileStatic so am not sure - but did Groovy have a pretty printed NPE
output at some point, that showed exactly where the null-pointer was
located in a call chain ?-)
In any case, could we supply that (at least in
@TypeChecked/@CompileDynamic) ?
I believe that the many measures languages have been and are taking to
avoid NPEs from occuring, often times are heading in the wrong direction
and would not be necessary if the exact location of a NPE in a call
chain was known when the NPE gets 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...
In Groovy 3.0.9 under OpenJDK 16:
@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" }
}
Cheers,
mg