Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-26481

Mishandling of binary methods accepting Closure

    Details

    • Type: Bug
    • Status: In Progress
    • Priority: Major
    • Resolution: Unresolved
    • Component/s: workflow-cps-plugin
    • Environment:
      Jenkins LTS 1.580.2 and workflow-plugin 1.1. Both are the latest versions at the time of this writing. Tested on RHEL 6 with OpenJDK 1.7 and Fedora 21 with OpenJDK 1.8.
    • Similar Issues:

      Description

      At least some closures are executed only once inside of Groovy CPS DSL scripts managed by the workflow plugin.

      Steps to reproduce:
      1. Create a new workflow with the following script:
      node {
      [1, 2, 3].each

      { println it }

      println "abc".replaceAll(/[a-z]/)

      { it.toUpperCase() }

      }
      2. Build the workflow

      Actual output:
      Started by user anonymous
      Running: Allocate node : Start
      Running on master in /var/lib/jenkins/jobs/testflow/workspace
      Running: Allocate node : Body : Start
      Running: Print Message
      1
      Running: Print Message
      A
      Running: Allocate node : Body : End
      Running: Allocate node : End
      Running: End of Workflow
      Finished: SUCCESS

      Expected output:
      Started by user anonymous
      Running: Allocate node : Start
      Running on master in /var/lib/jenkins/jobs/testflow/workspace
      Running: Allocate node : Body : Start
      Running: Print Message
      1
      Running: Print Message
      2
      Running: Print Message
      3
      Running: Print Message
      ABC
      Running: Allocate node : Body : End
      Running: Allocate node : End
      Running: End of Workflow
      Finished: SUCCESS

        Attachments

          Issue Links

            Activity

            Hide
            seblez Sébastien Varupenne added a comment - - edited

            I have a problem with pipeline. It says it's this problem :

            [Pipeline] // stage
            [Pipeline] stage
            [Pipeline] { (build-modules)
            [Pipeline] }
            [Pipeline] // stage
            [Pipeline] }
            [Pipeline] // node
            [Pipeline] End of Pipeline
            java.lang.UnsupportedOperationException: Calling public static java.util.Map org.codehaus.groovy.runtime.DefaultGroovyMethods.eachWithIndex(java.util.Map,groovy.lang.Closure) on a CPS-transformed closure is not yet supported (JENKINS-26481); encapsulate in a @NonCPS method, or use Java-style loops
            	at org.jenkinsci.plugins.workflow.cps.GroovyClassLoaderWhitelist.checkJenkins26481(GroovyClassLoaderWhitelist.java:90)
            	at org.jenkinsci.plugins.workflow.cps.GroovyClassLoaderWhitelist.permitsStaticMethod(GroovyClassLoaderWhitelist.java:60)
            	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:92)
            	at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:149)
            	at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:146)
            	at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:16)
            	at WorkflowScript.run(WorkflowScript:19)
            	at ___cps.transform___(Native Method)
            	at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:48)
            	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109)
            	at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82)
            	at sun.reflect.GeneratedMethodAccessor972.invoke(Unknown Source)
            	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            	at java.lang.reflect.Method.invoke(Method.java:498)
            	at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72)
            	at com.cloudbees.groovy.cps.impl.ClosureBlock.eval(ClosureBlock.java:46)
            	at com.cloudbees.groovy.cps.Next.step(Next.java:58)
            	at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154)
            	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18)
            	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33)
            	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30)
            	at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
            	at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30)
            	at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:163)
            	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:324)
            	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:78)
            	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:236)
            	at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:224)
            	at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:63)
            	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
            	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
            	at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
            	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
            	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
            	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
            	at java.lang.Thread.run(Thread.java:745)
            Finished: FAILURE
            

            here is my groovy pipeline code :

            node {
                stage('build-modules') {
                    def modules = [ 'FINANCE' : 'std-module-FINANCE-5_N9-4_manuel',
                                    'MOBILITE' : 'std-module-MOBILE-dev_integration-continue'
                                    ]
                    def buildMods = [:]
            
                    modules.eachWithIndex { module , i ->
                        buildMods["mod${i}"] = {
                            println "${module.key} will build ${module.value}"
                        }
                    }
                    parallel buildMods
                }
            }
            
            Show
            seblez Sébastien Varupenne added a comment - - edited I have a problem with pipeline. It says it's this problem : [Pipeline] // stage [Pipeline] stage [Pipeline] { (build-modules) [Pipeline] } [Pipeline] // stage [Pipeline] } [Pipeline] // node [Pipeline] End of Pipeline java.lang.UnsupportedOperationException: Calling public static java.util.Map org.codehaus.groovy.runtime.DefaultGroovyMethods.eachWithIndex(java.util.Map,groovy.lang.Closure) on a CPS-transformed closure is not yet supported (JENKINS-26481); encapsulate in a @NonCPS method, or use Java-style loops at org.jenkinsci.plugins.workflow.cps.GroovyClassLoaderWhitelist.checkJenkins26481(GroovyClassLoaderWhitelist.java:90) at org.jenkinsci.plugins.workflow.cps.GroovyClassLoaderWhitelist.permitsStaticMethod(GroovyClassLoaderWhitelist.java:60) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:92) at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:149) at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:146) at com.cloudbees.groovy.cps.sandbox.SandboxInvoker.methodCall(SandboxInvoker.java:16) at WorkflowScript.run(WorkflowScript:19) at ___cps.transform___(Native Method) at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:48) at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.dispatchOrArg(FunctionCallBlock.java:109) at com.cloudbees.groovy.cps.impl.FunctionCallBlock$ContinuationImpl.fixArg(FunctionCallBlock.java:82) at sun.reflect.GeneratedMethodAccessor972.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at com.cloudbees.groovy.cps.impl.ContinuationPtr$ContinuationImpl.receive(ContinuationPtr.java:72) at com.cloudbees.groovy.cps.impl.ClosureBlock.eval(ClosureBlock.java:46) at com.cloudbees.groovy.cps.Next.step(Next.java:58) at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:154) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$001(SandboxContinuable.java:18) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:33) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable$1.call(SandboxContinuable.java:30) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108) at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:30) at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:163) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:324) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$100(CpsThreadGroup.java:78) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:236) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:224) at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:63) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112) at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Finished: FAILURE here is my groovy pipeline code : node { stage('build-modules') { def modules = [ 'FINANCE' : 'std-module-FINANCE-5_N9-4_manuel', 'MOBILITE' : 'std-module-MOBILE-dev_integration- continue ' ] def buildMods = [:] modules.eachWithIndex { module , i -> buildMods[ "mod${i}" ] = { println "${module.key} will build ${module.value}" } } parallel buildMods } }
            Hide
            jglick Jesse Glick added a comment -

            You cannot use eachWithIndex or similar methods currently, sorry.

            Show
            jglick Jesse Glick added a comment - You cannot use eachWithIndex or similar methods currently, sorry.
            Hide
            jglick Jesse Glick added a comment -

            Idea to be tested: rather than using DGMPatcher, see if the use syntax can override DefaultGroovyMethods, possibly offering a solution for JENKINS-27421 as well. The problem is a bit of a chicken-and-egg: DefaultGroovyMethods.use(Object, Class, Closure) itself cannot be properly invoked.

            Show
            jglick Jesse Glick added a comment - Idea to be tested: rather than using DGMPatcher , see if the use syntax can override DefaultGroovyMethods , possibly offering a solution for JENKINS-27421 as well. The problem is a bit of a chicken-and-egg: DefaultGroovyMethods.use(Object, Class, Closure) itself cannot be properly invoked.
            Hide
            jglick Jesse Glick added a comment -

            Perhaps could have the CPS engine call GroovyCategorySupport private methods on a predefined category. use itself actually cannot work in a CPS transform; it would have to be applied to the whole CPS VM thread. Or perhaps DGMPatcher can be rewritten to use the tricks done in GroovyCategorySupport: DefaultMetaClassInfo.disabledStandardMC, VMPluginFactory.getPlugin().invalidateCallSites(), etc.

            Show
            jglick Jesse Glick added a comment - Perhaps could have the CPS engine call GroovyCategorySupport private methods on a predefined category. use itself actually cannot work in a CPS transform; it would have to be applied to the whole CPS VM thread. Or perhaps DGMPatcher can be rewritten to use the tricks done in GroovyCategorySupport : DefaultMetaClassInfo.disabledStandardMC , VMPluginFactory.getPlugin().invalidateCallSites() , etc.
            Hide
            kenorb kenorb added a comment - - edited

            Same here, I've Multi-line String Parameter (Params) with multi items like: Foo, Bar, Baz

            Then I'm trying to run this code:

            Params.split("\\r?\\n").each { param ->
                print "Param: ${param}"
            }
            

            Then I've got the error:

            java.lang.UnsupportedOperationException: Calling public static java.lang.Object org.codehaus.groovy.runtime.DefaultGroovyMethods.each(java.lang.Object,groovy.lang.Closure) on a CPS-transformed closure is not yet supported (JENKINS-26481); encapsulate in a @NonCPS method, or use Java-style loops

            Show
            kenorb kenorb added a comment - - edited Same here, I've Multi-line String Parameter (Params) with multi items like: Foo, Bar, Baz Then I'm trying to run this code: Params.split( "\\r?\\n" ).each { param -> print "Param: ${param}" } Then I've got the error: java.lang.UnsupportedOperationException: Calling public static java.lang.Object org.codehaus.groovy.runtime.DefaultGroovyMethods.each(java.lang.Object,groovy.lang.Closure) on a CPS-transformed closure is not yet supported ( JENKINS-26481 ); encapsulate in a @NonCPS method, or use Java-style loops

              People

              • Assignee:
                kohsuke Kohsuke Kawaguchi
                Reporter:
                dtschan Daniel Tschan
              • Votes:
                91 Vote for this issue
                Watchers:
                116 Start watching this issue

                Dates

                • Created:
                  Updated: