Search code examples
jenkinsgroovycloudbeesjenkins-workflow

Jenkins Groovy how to call methods from @NonCPS method without ending pipeline


I need to parse some JSON in a Jenkins Pipeline and call some regular methods in a loop, however the script always exits after the first function call. How to do this?

import groovy.json.JsonSlurper
import com.cloudbees.groovy.cps.NonCPS

@NonCPS
def myMethod(String json) {
    def jsonSlurper = new JsonSlurper()
    def jsonObject = jsonSlurper(json)
    jsonObject.each {
        obj ->
            switch(obj.name) {
                case "foo":
                    doAThing(obj)
                    break
                case "bar":
                    doAnotherThing(obj)
                    break
            }
    }
}

In the above example, even with a json object like:

[{
    "name": "foo"
}, {
    "name": "bar"
}]

...the pipeline always exits after the first iteration. This is presumably due to mixing sync and async functions. Is there any way to do this?


Solution

  • I've resolved this issue essentially by doing the following:

    import groovy.json.JsonSlurper
    
    def myMethod(String json) {
        def jsonSlurper = new JsonSlurper()
        def jsonObject = jsonSlurper(json)
        jsonSlurper = null
        for(int i = 0; i < jsonObject.size(); i++) {
            switch(jsonObject[i].name) {
                case "foo":
                    doAThing(jsonObject[i])
                    break
                case "bar":
                    doAnotherThing(jsonObject[i])
                    break
            }
        }
    }
    

    Immediately destroy the JsonSlurper instance after it's used, remove @NonCPS annotation, switch to a c-style for loop instead of each.