Need help understanding this NotSerializableException

18 views
Skip to first unread message

Hari Krishna Dara

unread,
Feb 5, 2019, 2:30:26 AM2/5/19
to Jenkins Users
I have a class that exposes a each style function that is working fine when called from many places of Jenkinsfile, but one such call needs to process it in reverse order, so I created a reverseEach style function, but this started throwing "java.io.NotSerializableException: org.codehaus.groovy.runtime.ReverseListIterator" exception. Here is the working function (order is just a list of strings):

    public List<String> eachDef(def body) {
        return order.each { name ->
            def bom_def = getDef(name)
            if (bom_def.enabled) {
                body.call(name, bom_def)
            }
        }
    }

Here is the reverse style function that uses reverseEach:

public List<String> reverseEachDef(def body) { return order.reverseEach { name -> def bom_def = getDef(name) if (bom_def.enabled) { body.call(name, bom_def) } } }

I even tried an alternative reverse but got the same error:

public List<String> reverseEachDef(def body) { // NOTE: list.reverse() is not currently whitelisted: org.jenkinsci.plugins.scriptsecurity.sandbox.RejectedAccessException: Scripts not permitted to use staticMethod org.codehaus.groovy.runtime.DefaultGroovyMethods reverse java.util.List return order.iterator().reverse().each { name -> def bom_def = getDef(name) if (bom_def.enabled) { body.call(name, bom_def) } } }

As a workaround, I used a plain for loop and it worked:

    public List<String> reverseEachDef(def body) {
        // NOTE: reverseEach() caused some weird: java.io.NotSerializableException: org.codehaus.groovy.runtime.ReverseListIterator
        for (int i = order.size() - 1; i >= 0; --i) {
            String name = order[i]
            def bom_def = getDef(name)
            if (bom_def.enabled) {
                body.call(name, bom_def)
            }
        }
    }

Looks like the issue in https://issues.jenkins-ci.org/browse/JENKINS-27421 but not fully addressed (as stated by some of the latest comments)?

I am running the following versions:

Jenkins: 2.89.3
Pipeline: 2.5
Script Security: 1.50




Hari Krishna Dara

unread,
Feb 11, 2019, 4:11:59 AM2/11/19
to Jenkins Users
I tried to reproduce this in a standalone pipeline, but the below code worked fine. The only difference between the failing code and the below test code is that the BOM class is defined inside a var file with a getter that creates an instance:

class BOM {
    private List order = ['a', 'b', 'c']
    
    def getDef(def name) {
        return [enabled: true]
    }

    public List<String> eachDef(def body) {
        return order.each { name ->
            def bom_def = getDef(name)
            if (bom_def.enabled) {
                body.call(name, bom_def)
            }
        }
    }
    
    public List<String> reverseEachDef(def body) {
        return order.reverseEach { name ->
            def bom_def = getDef(name)
            if (bom_def.enabled) {
                body.call(name, bom_def)
            }
        }
    }
}

def getBom() {
    return new BOM()
}

pipeline {
    agent "any"

    stages {
        stage('Init') {
            steps {
                script {
                    def bom = getBom()
                    bom.eachDef {name, bom_def -> echo "$name" }
                    bom.reverseEachDef {name, bom_def -> echo "$name" }
Reply all
Reply to author
Forward
0 new messages