-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
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
-
Maybe related to JENKINS-34428 and/or JENKINS-50731