-
Type:
Bug
-
Resolution: Unresolved
-
Priority:
Major
-
Component/s: workflow-cps-plugin
-
Environment:The latest and greatest, e.g. Jenkins (core) 2.115, workflow-cps 2.47
Like in JENKINS-50731:
Thanks to the fix of
JENKINS-45982I dared to continue with one of my original approaches using inheritance in shared Jenkins pipeline library classes, but stumbled over this problem.
I am not sure anymore (updated) whether or not this is really a bug: because I had already "qualifiyied" calls to 'acme.<steps>' with the script context (or so) also before switching back to using inheritance (thanks to the fix of JENKINS-45982) SpecialBuild below was basically duplicating things of Build like this:
class SpecialBuild { def script def acme SpecialBuild(def script) { this.script = script this.acme = script.acme } void build() { acme.build() { // ! Using the 'acme.build' step from 'vars/acme.groovy' script.node { acme.skipableStage("init") { // Direct usage of 'acme.skipableStage' step worked script.echo "acme 'Pipeline from SCM Script'" } acme.skipableStage('checkout') { // Direct usage of 'acme.skipableStage' step worked acme.svnCheckout('UpdateWithCleanUpdater') } } } } }
How to reproduce?
(I tried to include only minimal things and have not tested it after this "thinning out", so maybe there are small mistakes...)
"Jenkinsfile"
#!/usr/bin/env groovy echo 'Sandbox pipeline' @Library('acme-shared-library') _ acme.specialBuild() { }
Classes in shared pipeline library ('src' section)
- 'src/Build.groovy'
#!/usr/bin/env groovy class Build implements Serializable { def script def acme Build(def script) { this.script = Objects.requireNonNull(script, 'script must not be null') this.acme = script.acme } void build(Closure body) { try { body() } catch (e) { acme.notifyFailing(...) // Direct access/usage of 'acme' works here // While there would be no need to re-throw the exception to propagate the error (because the build result must be set // to failure for email-ext anyhow before), re-throw it for e.g. script approval requests: throw e } } }
- 'src/SpecialBuild.groovy'
#!/usr/bin/env groovy class SpecialBuild extends Build { SpecialBuild(def script) { super(script) } void build() { super.build() { // Mind this instead of 'acme.build()' like before using inheritance script.node { script.acme.skipableStage("init") { // This works script.echo "acme 'Pipeline from SCM Script'" } acme.skipableStage('checkout') { // ! This does NOT work acme.svnCheckout('UpdateWithCleanUpdater') } } } } }
Corresponding steps in shared pipeline library ('vars' section)
- 'vars/acme.groovy'
#!/usr/bin/env groovy void svnCheckout(String workspaceUpdater = 'UpdateUpdater') { // ... } void build(Map args, Closure body) { // ... def build = new Build(this) build.build(body) } void skipableStage(String stageName, Closure body) { skipableStage(stageName, false, body) } void skipableStage(String stageName, def skipCondition, Closure body) { skipableStage(stageName, skipCondition, null, body) } void skipableStage(String stageName, Closure skipBody, Closure body) { skipableStage(stageName, false, skipBody, body) } void skipableStage(String stageName, def skipCondition, Closure skipBody, Closure body) { // ... } void specialBuild() { // ... def acmeSpecialBuild = new SpecialBuild(this) acmeSpecialBuild.build() } void notifyFailing(...) { ... }
Current log/error
Note that this slightly differs to what would expect as it is from the original problem (with less reduced shared library code).
...
[Pipeline] echo
Sandbox pipeline
[Pipeline] node
Running on Jenkins in /var/lib/jenkins/workspace/Sandbox/acme.buildDockerImage
[Pipeline] {
[Pipeline] stage
[Pipeline] { (init)
[Pipeline] echo
acme 'Pipeline from SCM Script'
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // node
[Pipeline] echo
Pipeline problem: Build failed (init) due to: "groovy.lang.MissingMethodException: No signature of method: static acme.skipableStage() is applicable for argument types: (java.lang.String, org.jenkinsci.plugins.workflow.cps.CpsClosure2) values: [checkout, org.jenkinsci.plugins.workflow.cps.CpsClosure2@4faabfc3]
Possible solutions: skipableStage(java.lang.String, groovy.lang.Closure), skipableStage(java.lang.String, groovy.lang.Closure, groovy.lang.Closure), skipableStage(java.lang.String, java.lang.Object, groovy.lang.Closure), skipableStage(java.lang.String, java.lang.Object, groovy.lang.Closure, groovy.lang.Closure)" => Please check the "Console/Log Output" => Failure notification will be sent...
...
[Pipeline] // stage
[Pipeline] End of Pipeline
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: static acme.skipableStage() is applicable for argument types: (java.lang.String, org.jenkinsci.plugins.workflow.cps.CpsClosure2) values: [checkout, org.jenkinsci.plugins.workflow.cps.CpsClosure2@4faabfc3]
Possible solutions: skipableStage(java.lang.String, groovy.lang.Closure), skipableStage(java.lang.String, groovy.lang.Closure, groovy.lang.Closure), skipableStage(java.lang.String, java.lang.Object, groovy.lang.Closure), skipableStage(java.lang.String, java.lang.Object, groovy.lang.Closure, groovy.lang.Closure)
at groovy.lang.MetaClassImpl.invokeStaticMissingMethod(MetaClassImpl.java:1501)
at groovy.lang.MetaClassImpl.invokeStaticMethod(MetaClassImpl.java:1487)
at org.codehaus.groovy.runtime.callsite.StaticMetaClassSite.call(StaticMetaClassSite.java:53)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
at SpecialBuild.build(file:/var/lib/jenkins/jobs/Sandbox/jobs/acme.build/builds/12/libs/acme-shared-library/src/SpecialBuild.groovy:??)
at ___cps.transform___(Native Method)
at com.cloudbees.groovy.cps.impl.ContinuationGroup.methodCall(ContinuationGroup.java:57)
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.GeneratedMethodAccessor206.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:83)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:174)
at com.cloudbees.groovy.cps.Continuable$1.call(Continuable.java:163)
at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:122)
at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:261)
at com.cloudbees.groovy.cps.Continuable.run0(Continuable.java:163)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.access$101(SandboxContinuable.java:34)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.lambda$run0$0(SandboxContinuable.java:59)
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108)
at org.jenkinsci.plugins.workflow.cps.SandboxContinuable.run0(SandboxContinuable.java:58)
at org.jenkinsci.plugins.workflow.cps.CpsThread.runNextChunk(CpsThread.java:174)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:332)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244)
at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232)
at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131)
at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59)
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:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Finished: FAILURE
Workaround that works:
- Instead of calling acme.skipableStage(...) in SpecialBuild.build() => call script.acme.skipableStage(...)
- is related to
-
JENKINS-34428 workflow-cps-global-lib: inheritance (extends) not working
-
- Open
-
-
JENKINS-50731 Private methods of super class are "missing" in sub class
-
- Open
-
- relates to
-
JENKINS-50954 Field references in CPS class methods fail in CPS subclasses
-
- Open
-