Issue
I'm trying to delete a job in Jenkins from data retrieved from the git changelog. I can't use a @NonCPS function, because I'm using sh to launch the command, and I get
expected to call WorkflowScript.deleteJob but wound up catching sh; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/
When I remove the @NonCPS, as suggested in the link above, I get
java.io.NotSerializableException: org.jenkinsci.plugins.workflow.job.WorkflowJob
Here is the code that triggers the error (out of numerous other versions tried after looking up various answers in and out of StackOverflow):
// jobName computed by iterating on changeLogSets[i].items
stage ("delete job $jobName") {
println("before compute curl_command")
curl_command = "curl -X POST '$JENKINS_URL/job/$jobName/doDelete' -u user:secret"
println("after compute curl_command")
deleteJob(curl_command)
println("after deleteJob(curl_command)")
}
}
if (jobExists(jobName)) {
echo "inside try"
// echo "curl -X POST '$JENKINS_URL/job/$jobName/doDelete' -u fvila:11ae4ca260dac6d997db028c0cc8b26e29"
// sh "curl -X POST '$JENKINS_URL/job/$jobName/doDelete' -u fvila:11ae4ca260dac6d997db028c0cc8b26e29"
stage ("delete job $jobName") {
deleteJob(jobName)
}
}
echo "after doDelete"
// @NonCPS
def deleteJob(curlCommand) {
println("enter deleteJob(curlCommand)")
def output = sh curlCommand
// alternative :
sh curlCommand
println("exit deleteJob(curlCommand)")
}
def jobExists(jobName) {
println("enter jobExists, jobName=$jobName")
ret = jenkins.model.Jenkins.instance.getItem(jobName)
println("exit jobExists, ret=$ret")
return ret
}
here is a fuller copy of the error without @NonCPS
an exception which occurred:
in field groovy.lang.Closure.delegate
in object org.jenkinsci.plugins.workflow.cps.CpsClosure2@64d02d43
in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.closures
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@6616c092
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@6616c092
Caused: java.io.NotSerializableException: org.jenkinsci.plugins.workflow.job.WorkflowJob
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:274)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:345)
at java.base/java.util.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:333)
at java.base/java.util.HashMap.writeObject(HashMap.java:1412)
at org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:89)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:199)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1089)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1080)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:345)
at com.cloudbees.groovy.cps.SerializableScript.writeObject(SerializableScript.java:26)
at org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:89)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:199)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1089)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1080)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1080)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1080)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1080)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
at java.base/java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:345)
at java.base/java.util.HashMap.internalWriteEntries(HashMap.java:1858)
at java.base/java.util.HashMap.writeObject(HashMap.java:1412)
at org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:89)
at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:199)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1089)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1143)
at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1101)
at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:268)
at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)
at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111)
at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.lambda$writeObject$1(RiverWriter.java:144)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:237)
at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:143)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:559)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:536)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgramIfPossible(CpsThreadGroup.java:519)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:443)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$400(CpsThreadGroup.java:96)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:314)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:278)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:67)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:829)
Solution
The actual problem is the method "def jobExists(jobName)", which returns a job isntance, which is not serializable.
So this method should explicitly return boolean, which would fix your problem
boolean jobExists(jobName) {
This means that the job is correctly coerced into true or false using Groovy Truth, which is sufficient for your case.
Answered By - blackbuild
Answer Checked By - Clifford M. (JavaFixing Volunteer)