Pauline
Pauline

Reputation: 3836

Jenkins Pipeline throws a java.io.NotSerializableException: org.jenkinsci.plugins.workflow.job.WorkflowJob within a NonCPS method

I'm trying to get the data of another job within a @NonCPS method. It fails with a NotSerializableException even though the failing method is declared as @NonCPS.

The script is as follows - it only tries to get another job's data using its name and build number:

#!groovy

import jenkins.model.Jenkins

node('build_agent') {
  wrap([$class: 'AnsiColorBuildWrapper', 'colorMapName': 'xterm']) {
      stage('Get job details') {
          name = "another_jenkins_job"
          job = Hudson.instance.getJob(name)
          job_data = Jenkins.instance.getItemByFullName(job.fullName)
          jobNumber = "1234"
          println 'Job: ' + job.fullName
          getUpstreamJobData(job.fullName.trim(), buildNumber.trim())
      }
}

@NonCPS
def getUpstreamJobData(jobName, jobNumber) {
    println "Getting build #${jobNumber} from job ${jobName}"
    Jenkins.getInstance().getItemByFullName(jobName).getBuildByNumber(jobNumber)
}

The script fails, however, within the @NonCPS method getUpstreamJobData:

[Pipeline] echo
Job: another_jenkins_job
[Pipeline] echo
Getting build #1234 from job another_jenkins_job
[Pipeline] echo
Getting build #1234 from job another_jenkins_job
[Pipeline] echo
Getting build #1234 from job another_jenkins_job
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // wrap
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
an exception which occurred:
    in field delegate
    in field closures
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@1f5bb62e
Caused: java.io.NotSerializableException: org.jenkinsci.plugins.workflow.job.WorkflowJob
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860)
    at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
    at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
    ...

My understanding is that this failure usually happens when we return a non-serializable object outside of a Non-CPS method. However, the method here doesn't return anything yet, and it declared as NonCPS. Additionally the print statements seem to indicate that the method is executed 3 times while it is only called once.

Upvotes: 1

Views: 2730

Answers (2)

synapse
synapse

Reputation: 550

I had the very same issue because of missing def in front of one assignment inside a @NonCPS method. It seems, every assignment must be prefixed with def, otherwise job works as expected, but fails at the end when trying to save the finished build state.

Upvotes: 2

hakamairi
hakamairi

Reputation: 4678

So which part of your code is not serializable? Why do you think the exception is thrown from you @NonSCP method?

I think that those two look very suspicious

job = Hudson.instance.getJob(name)
job_data = Jenkins.instance.getItemByFullName(job.fullName)

Upvotes: 0

Related Questions