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
Originally reported by
solvingj, imported from: Groovy withIndex function doesn't work normally in pipeline
- assignee: vjuranek
- status: Open
- priority: Minor
- component(s): groovy-plugin
- resolution: Unresolved
- votes: 1
- watchers: 2
- imported: 20260604-161841
Raw content of original issue
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
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
// Run this locally in a groovy file or unit test
Originally reported by
solvingj, imported from: Groovy withIndex function doesn't work normally in pipeline
Raw content of original issue