Getting closure to work Pipeline

145 views
Skip to first unread message

Hari Krishna Dara

unread,
Aug 27, 2018, 2:56:32 AM8/27/18
to Jenkins Users
I am trying out an approach in which the caller receives a closure as a return value from a function so that the context can be preserved for further call chaining. I tried the below as a test and it didn't work:

def prep() {
    return [run: {-> echo "Hello Closure"}]
}

pipeline {
    agent "any"

    stages {
        stage("Init") {
            steps {
                script {
                    p = prep()
                    p.run()
                }
            }
        }
    }
}


The error I see in the console log is:

hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.util.LinkedHashMap.run() is applicable for argument types: () values: []
Possible solutions: min(groovy.lang.Closure), put(java.lang.Object, java.lang.Object), put(java.lang.Object, java.lang.Object), find(), any(), grep()
	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:131)
	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:155)
	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:159)
	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:17)
	at WorkflowScript.run(WorkflowScript:14)
	at ___cps.transform___(Native Method)
...

When I tried to return the closure directly instead of a map it worked fine:

def prep() {
    return {-> echo "Hello Closure"}
...
                    p = prep()
...


Also, if I extract the map element first, it works fine (when I called the local variable as run, I got the script security error: Scripts not permitted to use method java.lang.Runnable run):

                    p = prep()
                    r = p.run
                    r()

And this works too:

                    p = prep()
                    p["run"]()


but this is not elegant. Is this a bug or expected behavior? The below equivalent worked fine in script console:

def prep() {
    return [run: {-> print("Hello Closure")}]
}

prep().run()


Hari Krishna Dara

unread,
Aug 28, 2018, 8:10:57 AM8/28/18
to Jenkins Users
I found the closure composition feature and it works well for the use case that I had in mind. However, it would be interesting to understand why the below fails. Should I create a bug?
Reply all
Reply to author
Forward
0 new messages