How to fix NotSerializableException error during Jenkins workflow build?
Asked Answered
P

2

20

When I run the following code on the Jenkins workflow (Jenkins 1.609.1 ,workflow 1.8) I get error of 'NotSerializableException' (also below). However, if I move the "build job" outside the "for" scope it works fine (the job is activated). Any ideas why this behavior?

node('master') { 
ws('/opt/test) {
def file = "/ot.property"
def line = readFile (file)
def resultList = line.tokenize()
for(item in resultList )
  {
build job: 'testjob_1'
   }
 }
}

Got error:

Running: End of Workflow 
java.io.NotSerializableException: java.util.ArrayList$Itr  
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854)
    at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032)  


.....
Pleasurable answered 27/7, 2015 at 13:32 Comment(1)
For me I found the best and simplest workaround here: https://mcmap.net/q/518397/-impossibility-to-iterate-over-a-map-using-groovy-within-jenkins-pipelineAzerbaijani
M
25

I thnk it is because it's trying to serialize the unserializable item iterator on resultList as soon as it hits the build job step. See here for guidance on use of nonserializable variables:

https://github.com/jenkinsci/workflow-plugin/blob/master/TUTORIAL.md#serialization-of-local-variables

As a workaround to safely iterate using the workflow plugin, you need to us C-style loops. Try this instead:

for ( int i = 0; i < resultList.size; i++ ) {
  etc...
Maidy answered 27/7, 2015 at 16:46 Comment(4)
Further reference here: <groups.google.com/d/msg/jenkinsci-users/LGRv7Jq60YI/…>Maidy
tnx, seems better now!Pleasurable
FYI, this particular error is tracked as JENKINS-27421.Fraze
But how can I do the same for maps?Turnbuckle
S
9

According to CloudBees Platform Help page:

By design the pipeline can only keep records of Serializable objects. If you still need to keep an intermediate variable with a non serializable object, you need to hide it into a method and annotate this method with @NonCPS.

So you should transform your code into a function with @NonCPS helper method.

Related Jenkins bug: JENKINS-27421.

Shagbark answered 23/10, 2016 at 18:36 Comment(2)
Yep. found this beautiful example to that effect: gist.github.com/oifland/ab56226d5f0375103141b5fbd7807398Plow
Important thing to keep in mind here: you can't execute pipeline steps from an @NonCPS method! groups.google.com/forum/#!topic/jenkinsci-users/VXrSVBZ2maUTractable

© 2022 - 2024 — McMap. All rights reserved.