Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-62680

Groovy withIndex function doesn't work normally in pipeline

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor
    • groovy-plugin
    • None

      Note:

      While this problem can be VERY confusing to diagnose depending on the situation, it does have a very reasonable workaround:
      Instead of doing:
      jsonArray.withIndex().each{Object str, Integer index -> currentBuild.echo("${idx.toString()} : ${str}")}
      We can do:
      jsonArray.withIndex().each{Tuple2 tuple2 -> currentBuild.echo("${tuple2.first} : ${tuple2.second}")}


      Groovy adds withIndex() method to iterables which turns each element into a Tuple2 of Element + index.  When using any of the groovy collection methods following withIndex(), Groovy then typically deconstructs the Tuple2 in the closure, but that doesn't seem to happen when using withIndex() on Jenkins. 

      The outputs below demonstrate the issue pretty clearly.  
       

      // Run this in a Jenkins step

      String jsonStr = "['zero', 'one', 'two']"
      JSONArray jsonArray = new JsonSlurper().parseText(jsonStr) as JSONArray
      jsonArray.withIndex().each{Object str, Integer idx -> currentBuild.echo("${idx.toString()} : ${str}")}
      // OUTPUT from jenkins
      // [Pipeline] echo
      // null : [zero, 0]
      // [Pipeline] echo
      // null : [one, 1]
      // [Pipeline] echo
      // null : [two, 2]

      // Run this locally in a groovy file or unit test

      String jsonStr = "['zero', 'one', 'two']"
      JSONArray jsonArray = new JsonSlurper().parseText(jsonStr) as JSONArray
      jsonArray.withIndex().each{Object str, Integer idx -> println("${idx.toString()} : ${str}")}
      // OUPUT Local
      // 0 : zero
      // 1 : one
      // 2 : two

          [JENKINS-62680] Groovy withIndex function doesn't work normally in pipeline

          FYI, I had to use getFirst() instead of first on Tuple2:

           

          org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field java.lang.String first
          	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:426)
          	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:410)

           

          Specifically

          This works in groovysh:

          groovy:000> ['one', 'two', 'three'].withIndex().collect { element, index -> element + index }
          ===> [one0, two1, three2]
          
          groovy:000> ['one', 'two', 'three'].withIndex().collect { Tuple2 t -> t.first + t.second }
          ===> [one0, two1, three2]
          

          but not in Jenkins Pipeline.

          This works in Jenkins Pipeline:

           

           ['one', 'two', 'three'].withIndex().collect { Tuple2 t -> t.getFirst() + t.getSecond() }

           

          Jenkins 2.302, Groovy 2.4.12

          Alexander Komarov added a comment - FYI, I had to use getFirst() instead of first on Tuple2:   org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: No such field found: field java.lang.String first at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.unclassifiedField(SandboxInterceptor.java:426) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onGetProperty(SandboxInterceptor.java:410)   Specifically This works in  groovysh : groovy:000> ['one', 'two', 'three'].withIndex().collect { element, index -> element + index } ===> [one0, two1, three2] groovy:000> ['one', 'two', 'three'].withIndex().collect { Tuple2 t -> t.first + t.second } ===> [one0, two1, three2] but not in Jenkins Pipeline . This works in Jenkins Pipeline:   ['one', 'two', 'three'].withIndex().collect { Tuple2 t -> t.getFirst() + t.getSecond() }   Jenkins 2.302, Groovy 2.4.12

            vjuranek vjuranek
            solvingj jerry wiltse
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: