Uploaded image for project: 'Groovy'
  1. Groovy
  2. GROOVY-4954

Currying closure with null as argument fails with NPE

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Closed
    • Major
    • Resolution: Fixed
    • 1.8.0, 1.8.1, 1.9-beta-1
    • 1.9-beta-4
    • None
    • None

    Description

      Trying to curry a closure with null as a parameter throws NullPointerException. With Groovy 1.7.10 it works as expected, i.e. sets the first closure argument to null.

      Example using Groovy 1.8.1:

      { x, y -> x ?: y }.curry(null)
      
      java.lang.NullPointerException
      	at org.codehaus.groovy.runtime.CurriedClosure.<init>(CurriedClosure.java:54)
      	at org.codehaus.groovy.runtime.CurriedClosure.<init>(CurriedClosure.java:86)
      	at groovy.lang.Closure.curry(Closure.java:527)
      	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:90)
      	at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:233)
      	at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:272)
      	at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:883)
      	at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:39)
      	at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:42)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
      	at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
      [...]
      
      // The workaround is this:
      assert { x, y -> x ?: y }.curry([null] as Object[])(3) == 3
      

      Groovy 1.7.10 works as expected:

      assert { x, y -> x ?: y }.curry(null)(3) == 3
      assert { x, y -> x ?: y }.curry([null] as Object[])(3) == [null]
      

      CurriedClosure constructor changed between 1.7 and 1.8:

      $ diff 1.7.10/.../CurriedClosure.java 1.8.1/.../CurriedClosure.java
      49c49
      <     public CurriedClosure(int index, Closure uncurriedClosure, Object[] arguments) {
      ---
      >     public CurriedClosure(int index, Closure<V> uncurriedClosure, Object... arguments) {
      

      arguments parameter in 1.8 is set to null instead of [null] when invoking curry(null), hence the exception on line 54 of CurriedClosure class.

      Attachments

        Activity

          People

            paulk Paul King
            dsrkoc Dinko Srkoc
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: