Search code examples
jenkinsgroovyjenkins-pipeline

How to avoid cps error using XmlSlurper() method in jenkins pipeline


I am using a simple test pipeline to get a username out of a xml file, I have written a simple function using the XmlSlurper method and I have included the @NonCPS annotation at the beginning of the function but I keep getting an error, even though the function seems to work as it prints out in the console the username I am trying to find but it finishes the build with failure status. This is the pipeline:

import groovy.xml.*
import jenkins.model.Jenkins


@NonCPS
def findComitter(){
    committer = ""
    found = false 
    file = new XmlSlurper().parse("C:/Users/User/.jenkins/jobs/Phoenix_pipeline/builds/288/changelog6429015253614530280.xml")
    file.entry.each { entry ->
        entry.changenumber.each { changenumber ->
            changenumber.children().each { tag ->
                if(tag.name() == "changeUser" && found != true){
                    committer = tag.text()
                    found = true
                }
            }
        }
    }
    println committer
    //return committer.toString()
}

pipeline {
    agent any

    stages {
        stage('test') {
            steps {
                findComitter()
            }
        }
    }
}

this is the output I get, as you can see the function call seems to work as it get to the println commiter step but then I get an error and failure build status:

00:00:00.114  [Pipeline] {
00:00:00.129  [Pipeline] stage
00:00:00.132  [Pipeline] { (test)
00:00:00.158  [Pipeline] echo
00:00:00.161  jaydenm
00:00:00.163  [Pipeline] }
00:00:00.170  [Pipeline] // stage
00:00:00.178  [Pipeline] }
00:00:00.189  [Pipeline] // node
00:00:00.211  [Pipeline] End of Pipeline
00:00:00.236  an exception which occurred:
00:00:00.236    in field org.jenkinsci.plugins.pipeline.modeldefinition.withscript.WithScriptScript.script
00:00:00.236    in object org.jenkinsci.plugins.pipeline.modeldefinition.agent.impl.LabelScript@135cdcd8
00:00:00.236    in field groovy.lang.Closure.delegate
00:00:00.236    in object org.jenkinsci.plugins.workflow.cps.CpsClosure2@7e549176
00:00:00.236    in field groovy.lang.Closure.delegate
00:00:00.236    in object org.jenkinsci.plugins.workflow.cps.CpsClosure2@6db041bd
00:00:00.236    in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.closures
00:00:00.236    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@5a72dabe
00:00:00.236    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@5a72dabe
00:00:00.236  Caused: java.io.NotSerializableException: groovy.util.slurpersupport.NodeChild

I have been looking through the SO threads and all the info I got is to use the @NonCPS annotation to use any non-serializable objects, which I have done.


Solution

  • You may be creating global objects. Try def to create local objects:

    @NonCPS
    def findComitter(){
        def committer = ""
        def found = false 
        def file = new XmlSlurper().parse(...)