Details
Description
We enhance the NullObject to have a more graceful null handling.
def emc = new ExpandoMetaClass( org.codehaus.groovy.runtime.NullObject.getNullObject().getClass()) emc.plus = {b -> b} emc.initialize() org.codehaus.groovy.runtime.NullObject.getNullObject().setMetaClass(emc) It works fine except for some variants of array access: Double[][] a = new Double[10][10] for (def i = 0; i <= 9; i++ ) { for (def j = 0; j <= 9; j++ ) { println("i=$i j=$j a[0][i]=$a[0][i]") a[0][i] = a[0][i] + 1 } }
We get a NPE:
java.lang.NullPointerException at org.codehaus.groovy.runtime.dgmimpl.NumberNumberPlus$DoubleInteger.call(NumberNumberPlus.java:170) at ConsoleScript6.run(ConsoleScript6:10) at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:264) at groovy.lang.GroovyShell.run(GroovyShell.java:513) at groovy.lang.GroovyShell.run(GroovyShell.java:170) at groovy.lang.GroovyShell$run$0.call(Unknown Source) at groovy.ui.Console$_runScriptImpl_closure16.doCall(Console.groovy:890) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:273) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886) at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.callCurrent(PogoMetaClassSite.java:66) at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callCurrent(AbstractCallSite.java:149) at groovy.ui.Console$_runScriptImpl_closure16.doCall(Console.groovy) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:88) at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233) at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:273) at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:886) at groovy.lang.Closure.call(Closure.java:276) at groovy.lang.Closure.call(Closure.java:271) at groovy.lang.Closure.run(Closure.java:354) at java.lang.Thread.run(Thread.java:619)
A script to reproduce this in the GroovyConsole is attached.