I am getting "No signature" error when the body() method calls in my pipeline groovy script
I was using Jenkins shared library for pipeline project. I have configured the shared library in my local Jenkins. When I tried to hit my shared library, it is getting called properly but I am not able to resolve the parameters values which is coming in my shared library call()
method.
My Share Library code ( myDeliveryPipeline.groovy
)
def call(body) {
println(body)
// evaluate the body block, and collect configuration into the object
def pipelineParams= [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = pipelineParams
body()
println (pipelineParams.BRANCH)
println 'Map'
println body
println 'pipelineParams'
println pipelineParams
println 'Start pipeline steps'
// our complete declarative pipeline can go in here
pipeline {
agent any
// Stage checkout git
stages {
stage('checkout git') {
steps{
git branch: 'master', url:'MY_GIT_HUB_URL'
}
}
//checkout git ends
// stage build
stage('build') {
steps{
script{
if(isUnix()){
sh 'mvn clean package -Dmaven.test.skip=true'
}
else{
bat('mvn clean install -Dmaven.test.skip=true')
}
}
}
}
// stage build ends
// stage Test
stage ('test') {
steps{
script{
if('yes' == 'yes'){
if(isUnix()){
parallel (
"unit tests": { sh 'mvn test' },
"integration tests": { sh 'mvn integration-test' }
)
}
else{
parallel (
"unit tests": { bat('mvn test')},
"integration tests": { bat('mvn integration-test')}
)
}
}
}
}
}
// stage Test Ends
}
post {
failure {
mail to: 'MAIL_ID@gmail.com', subject: 'Pipeline failed', body: "${env.BUILD_URL}"
}
success{
println "SUCCESS"
}
}
}
}
My Jenkins File
properties ([
parameters([
string(name: 'BRANCH', defaultValue: 'master', description: 'Branch to build'),
choice(name: 'RUN_TEST', choices: ['yes', 'no'], description: 'Run test while build'),
booleanParam(name: 'MAIL_TRIGGER', defaultValue: true, description: 'mail to be triggred'),
string(name: 'EMAIL', defaultValue: 'MY_EMAIL@gmail.com', description: 'Mail to be notified')
])
])
@Library('my-pipeline-library') _
myDeliveryPipeline(BRANCH:params.BRANCH, RUN_TEST:params.RUN_TEST, MAIL_TRIGGER:params.MAIL_TRIGGER, EMAIL:params.EMAIL)
Logs from my job
> C:\Program Files\Git\bin\git.exe rev-list --no-walk 2fdeb821e0ecec40e53b2e0bdd6608840914422b # timeout=10
[Pipeline] properties
[Pipeline] echo
{BRANCH=master, RUN_TEST=yes, MAIL_TRIGGER=true, EMAIL=MAIL_ID@gmail.com}
[Pipeline] End of Pipeline
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.util.LinkedHashMap.call() is applicable for argument types: () values: []
Possible solutions: wait(), any(), wait(long), any(groovy.lang.Closure), take(int), any(groovy.lang.Closure)
at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.unwrap(ScriptBytecodeAdapter.java:58)
at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:49)
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 myDeliveryPipeline.call(C:\Program Files (x86)\Jenkins\jobs\TestJenkinsFile\builds\43\libs\my-pipeline-library\vars\myDeliveryPipeline.groovy:10)
at WorkflowScript.run(WorkflowScript:14)
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.fixName(FunctionCallBlock.java:77)
at sun.reflect.GeneratedMethodAccessor255.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
In the shared library file vars/myDeliveryPipeline.groovy
, the signature of call
is call(<Closure>)
.
However, I see you are calling it as it is call(<Map>)
.
Thus, call it :
myDeliveryPipeline {
BRANCH=params.BRANCH
RUN_TEST=params.RUN_TEST
MAIL_TRIGGER=params.MAIL_TRIGGER
EMAIL=params.EMAIL
}
Instead of : myDeliveryPipeline(BRANCH:params.BRANCH, RUN_TEST:params.RUN_TEST, MAIL_TRIGGER:params.MAIL_TRIGGER, EMAIL:params.EMAIL)
.
By now, the signature is fixed, but I can see that you override the DELEGATION of the closure (body) from Jenkins to a Map. As consequence, params
is undefined.
Thus, I suggest to overload call(<Closure>)
with call(<Map>, <Closure>)
.
def call(body) {
call([:], body)
}
def call(pipelineParams, body) {
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = pipelineParams
body()
//...
}
By now, the call can be :
myDeliveryPipeline(
BRANCH:params.BRANCH,
RUN_TEST:params.RUN_TEST,
MAIL_TRIGGER:params.MAIL_TRIGGER,
EMAIL:params.EMAIL
) {}
Do not forget the last {}
.
Briefly :
If you want to inject pipeline variables (ie: params,...) , inject them in Map
using signature myDeliveryPipeline(Map,Closure)
even if the closure is empty.
If you are not depending on Pipeline variables, you can use Closure
by using the signature myDeliveryPipeline(Closure)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.