'sh command in Jenkins pipeline fails with and without @NonCps

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 1:[1]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 blackbuild