workflow-plugin Serialisation issues when iterating over a list of strings

2,124 views
Skip to first unread message

Robin Tegg

unread,
Feb 9, 2015, 8:48:11 AM2/9/15
to jenkins...@googlegroups.com
Hi all,

I've been trying out the workflow plugin after watching the pimp-your-continuous-delivery-pipeline-with-jenkins-workflow-wjax-14 demo. And in one of the slides (24), there is an example of a for loop that looks to iterate over a list of hostnames. I've assumed that hostnames is a list

def hostnames = ["192.168.0.1", "192.168.0.2"]
for( def hostname: hostnames ) {
    sh "ssh ${hostname} ..."
  }

I'm wondering if anyone can help with my usage of arrays/lists. I'm getting the following errors when I try the above:

java.io.NotSerializableException: java.util.AbstractList$Itr

Now I understand from the docs (https://github.com/jenkinsci/workflow-plugin/blob/master/TUTORIAL.md#serialization-of-local-variables) that some variables can't be serialized before a "sh" step might happen, but as I'm new to groovy I'm struggling to understand how the above might be achieved. I've tried in a method and inline as suggested.

The workaround I have at the moment is

def hostnames = ["192.168.0.1", "192.168.0.2"]
for( int i = 0; i < hostnames.size(); i++) {
  sh "ssh ${hostnames.get(i)} ..."
}

Any pointers would be much appreciated

Thanks
Robin

Brian Ray

unread,
Feb 9, 2015, 12:25:52 PM2/9/15
to jenkins...@googlegroups.com
Hi Robin,

The simplest Groovy idiom for iterating over a collection is

hostnames.each { host ->
 
do something interesting with host ...
}



Does this work?

Brian

Brian Ray

unread,
Feb 9, 2015, 12:35:34 PM2/9/15
to jenkins...@googlegroups.com
Another stab in the dark. The double quotes mean the individual hostnames are GStrings instead of Strings. Maybe starting this way:

def hostnames = ['192.168.0.1', '192.168.0.2']

Daniel Beck

unread,
Feb 9, 2015, 12:47:04 PM2/9/15
to jenkins...@googlegroups.com
'each' is currently broken in Workflow CPS scripts.

https://issues.jenkins-ci.org/browse/JENKINS-26481
> --
> You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/9dde8b3d-04a5-4644-96a0-2930f78c4978%40googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

Robin Tegg

unread,
Feb 10, 2015, 11:04:26 AM2/10/15
to jenkins...@googlegroups.com
Brian,

Thanks for you help.

Not sure why this wasn't working for me yesterday, it might have been a scoping issue??

I can confirm that if I use the following inside a node{} block:

def bees = ["192.168.0.1", "192.168.0.2"]
 
for( def b: bees ) {
    echo
"${b}"
 
}

then I get the expected output

Robin Tegg

unread,
Feb 10, 2015, 11:05:12 AM2/10/15
to jenkins...@googlegroups.com, m...@beckweb.net
Daniel,

Thanks for the .each pointer, that's saved me some head scratching

Robin

Jesse Glick

unread,
Feb 25, 2015, 6:26:28 PM2/25/15
to jenkins...@googlegroups.com
On Monday, February 9, 2015 at 8:48:11 AM UTC-5, Robin Tegg wrote:
java.io.NotSerializableException: java.util.AbstractList$Itr

Indeed this class in the JRE, which is used for JDK 5-style for-loops, is not serializable and so this idiom cannot be used from a flow build (which must survive Jenkins restarts). Whether we can hack around that or not, I am not sure. In the meantime, use C-style loops with an index.
Reply all
Reply to author
Forward
0 new messages