Search code examples
jenkinsjenkins-pipelinejenkins-groovy

Jenkins Pipeline: java.io.NotSerializableException with XmlUtil.serialize


I'm facing an issue in my Jenkins pipeline where I get a java.io.NotSerializableException when using XmlUtil.serialize.

Code Snippet:

de updateFile() {
   def file = readFile(file: filePath)
   def xml = new XmlSlurper().parseText(file)

   ... update XML

   def modifiedXml = XmlUtil.serialize(xml)
   writeFile(file: filePath, text: modifiedXml)
}

pipeline {
    agent {
        label 'agent-1'
    }

    stages {
        stage('Update File') {
            steps {
                updateFile()
            }
        }
    }
}

Error Message

Caused: java.io.NotSerializableException: groovy.util.slurpersupport.NodeChild

I am running this on another server as a Jenkins Agent. I tried @NonCPS also but it is not working also. So anybody can help me to resolve this?


Solution

  • According to https://www.jenkins.io/doc/book/pipeline/cps-method-mismatches/, you must not use pipeline steps in @NonCPS-ed methods -- that's probably the reason why this solution fails for you.

    However, the problem is indeed related to the CPS transformation I think. You can work around it, however, without even using @NonCPS. Moving the XML-related operations into a separate function will do the trick. The following does work fine:

    import groovy.xml.XmlUtil
    
    filePath = 'test.xml'
    
    def updateFile2(file) {
        def xml = new XmlSlurper().parseText(file)
    
       //... update XML
       // e.g.
       // xml.bar = 'baz'
    
       def modifiedXml = XmlUtil.serialize(xml)
       return modifiedXml
    }
    
    def updateFile() {
        def file = readFile(file: filePath)
        def modifiedXml = updateFile2(file)
        writeFile(file: filePath, text: modifiedXml)
    }
    
    pipeline {
        agent {
            label 'agent-1'
        }
        stages {
            stage('Update File') {
                steps {
                    updateFile()
                }
            }
        }
    }
    

    Apparently, the CPS-transformation fails when you mix pipeline steps and XML methods in the same function; putting the calls into different functions avoids that issue.