Hi there,

if the NPE management is being worked on, I'd like to again advocate for a way 
to switch on a “default-safe” mode, be it a compiler switch, an annotation, 
whatever.

With this mode on, the compiler would use the “safe“ (more precisely, 
null-propagation) mode by default all the time without forcing the programmer 
to use all those pesky question marks explicitly (or, as I do, to add ASTTs to 
make exp.safe=true everywhere, along with a couple of other tricks to turn NPEs 
which I hate very much to the consistent ubiquitous null-propagation which I 
very strongly prefer).

(As for the problem with external libraries, I am currently considering 
wrapping all the external library calls into a try/catch harness which would 
catch NPE and return a null in this case. I would, actually; but the one 
problem I haven't solved yet is to recognise an external library call; at the 
moment a foo.bar() is being compiled, nobody knows whether the bar method is my 
own compiled code or an external library, for nobody knows what foo contains :/ 
Perhaps this might be solved at runtime though, checking at the moment a method 
is being dispatched?)

Thanks and all the best,
OC

> On 19 Sep 2021, at 17:46, MG <mg...@arscreat.com> wrote:
> 
> 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://openjdk.java.net/jeps/358>
> https://www.baeldung.com/java-14-nullpointerexception 
> <https://www.baeldung.com/java-14-nullpointerexception>
> https://bugs.openjdk.java.net/browse/JDK-8233014 
> <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
> 
> 

Reply via email to