MissingMethodException while using shared libraries

453 views
Skip to first unread message

Kaliyug Antagonist

unread,
Mar 1, 2019, 2:50:57 AM3/1/19
to Jenkins Users

Cloudbees 2.121.3.1


Partial Jenkinsfile of the main component that is failing viz. Alfaclient:

properties([parameters([string(defaultValue: "", description: "List of components", name: 'componentsToUpdate'),
                        string(defaultValue: "refs%2Fheads%2Fproject%2Fintegration", description: "BuildInfo CommitID", name: 'commitId'),
                        string(defaultValue: "", description: "Tag to release, e.g. 1.1.0-integration", name: 'releaseTag'),
                        string(defaultValue: "", description: "Forked buildInfo repo. Be aware right commit ID!!!", name: 'fork')]),
                        [$class: 'BuildDiscarderProperty', strategy: [$class: 'LogRotator', artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '7', numToKeepStr: '5']],
                        disableConcurrentBuilds()])

@Library(['jenkins-shared-utilities@integration/CICD-344-refactor-bitbucket-notify-handler','jenkins-shared-stages@integration/CICD-344-refactor-bitbucket-notify-handler','jenkins-shared-pipelines@integration/CICD-344-refactor-bitbucket-notify-handler']) _
.
.
.
returnValue = componentPipeline {
        componentsToUpdate = rewriteDependencies
        commitId = buildInfoCommitId
        runOnForkedRepo = forkedRepo
    }


The componentPipeline in the above code is a scripted pipeline located in vars of jenkins-shared-pipelines The partial Jenkinsfile(which doesn't do much!) of jenkins-shared-pipelines

#!groovy

@Library(['jenkins-shared-utilities@integration/CICD-344-refactor-bitbucket-notify-handler','jenkins-shared-stages@integration/CICD-344-refactor-bitbucket-notify-handler']) _


Partial code for componentPipeline:

def call(body) {
    def config = [:]
    body.resolveStrategy = Closure.DELEGATE_FIRST
    def componentName = null
    body.delegate = config
    body()
    def rewriteDependency = config.componentsToUpdate
    def buildInfoCommitId = config.commitId
    def forkedBuildInfo = config.runOnForkedRepo

    def PIPELINE_NAME = "Component Pipeline"
    .
    .
    .
    setupSharedUtils(callingScript: this)
    .
    .
    .
    def build_status = "ok"
            stage(CLEAN_STAGE) {
            .
            .
            .
            bitbucketUtilities.notifyBuildStart("Build ${env.BUILD_ID} started at ${env.BUILD_TIMESTAMP}", PIPELINE_NAME)

            }
            stage(GET_BUILD_INFO) {
            .
            .
            .
            build_status = "${COMPILE_STAGE} failed in build ${env.BUILD_ID} with exit code ${exit_code}"
            bitbucketUtilities.notifyBuildFail(build_status, PIPELINE_NAME)

            }   

}


Now comes the main library viz. jenkins-shared-utilities. It has the following structure: 


vars containing scripts that would act as global variables for components like Alfaclient.

bitbucketUtilities.groovy

import groovy.transform.Field
import com.jenkins.utilities.bitbucket.*
import com.cloudbees.groovy.cps.NonCPS

@Field final String STEP_NAME = getClass().getName()
@Field final BitbucketBuildOperationsHandler bitbucketUtilities = new BitbucketBuildOperationsHandler(this,env)

@NonCPS
def notifyBuildStart(String message, String displayName) {

    //Remove
    println "bitbucketUtilities global vars, env: "+env
    validateCall(this, message, displayName)

    bitbucketUtilities.notifyBuildStart(message, displayName)
}

@NonCPS
def notifyBuildSuccess(String message, String displayName) {

    //Remove
    println "bitbucketUtilities global vars, env: "+env

     validateCall(this, message, displayName)

    bitbucketUtilities.notifyBuildSuccess(message, displayName)
}

@NonCPS
def notifyBuildFail(String message, String displayName) {

    //Remove
    println "bitbucketUtilities global vars, env: "+env

    validateCall(this, message, displayName)

    bitbucketUtilities.notifyBuildFail(message, displayName)
}

@NonCPS
private void validateCall(def script, String message, String displayName) {

    if(message == null || message.isEmpty()) {
        script.error("[ERROR][${script.STEP_NAME}] Build message not provided")
    }

    if(displayName == null || displayName.isEmpty()){
        script.error("[ERROR][${script.STEP_NAME}] displayName not provided!")
    }

}

setupSharedUtils.groovy

import groovy.transform.Field
import com.jenkins.utilities.ServiceLocator

void call(Map parameters = [:]) {
    if (parameters?.callingScript == null) {
        step.error(
            "[ERROR][setupSharedUtils] No reference to surrounding script " +
            "provided with key 'callingScript', e.g. 'callingScript: this'.")
    } else {
        parameters.callingScript.serviceLocator = ServiceLocator.getInstance()
    }
}


src packages containing classes like BitbucketBuildOperationsHandler

class BitbucketBuildOperationsHandler implements  Serializable {

    private def script
    private def env
    //TODO: Think if this should be an enum but iterating it will be an overhead
    private static final String [] bitbucketBuildStatuses = ["INPROGRESS", "SUCCESSFUL", "FAILED"]

    BitbucketBuildOperationsHandler(def script, def env) {
        //Remove
        script.println "In constructor of BitbucketBuildOperationsHandler, env: {$env}, script: {$script}"
        this.script = script
        this.env = env
    }

    def notifyBuildStart(String message, String displayName) {
        script.println "${displayName} Notify commit: ${env.GIT_COMMIT} build start: ${message}"
        postBuildStatus(script,"INPROGRESS", displayName, env.BUILD_URL, env.GIT_COMMIT, message)
    }

    def notifyBuildSuccess(String message, String displayName) {
        script.println "${displayName} Notify commit: ${env.GIT_COMMIT} build success: ${message}"
        postBuildStatus(script,'SUCCESSFUL', displayName, env.BUILD_URL, env.GIT_COMMIT, message)
    }

    def notifyBuildFail(String message, String displayName) {
        script.println "${displayName} Notify commit: ${env.GIT_COMMIT} build fail: ${message}"
        postBuildStatus(script,'FAILED', displayName, env.BUILD_URL, env.GIT_COMMIT, message)
    }

.
.
.   
}

*****Error*****

While the library jenkins-shared-utilities seems to be available to Alfaclient, somehow, in the global vars bitbucketUtilities.groovy, the variable 'bitbucketUtilities' (@Field final BitbucketBuildOperationsHandler bitbucketUtilities) isn't identified. Note that the @NonCPS annotation is immaterial - the Exception persists with/without it, also, note the println in bitbucketUtilities global vars and in the constructor of Groovy class viz. BitbucketBuildOperationsHandler

In constructor of BitbucketBuildOperationsHandler, env: {org.jenkinsci.plugins.workflow.cps.EnvActionImpl@75f03f42}, script: {bitbucketUtilities@3e86aed8}
[Pipeline] echo
bitbucketUtilities global vars, env: org.jenkinsci.plugins.workflow.cps.EnvActionImpl@75f03f42
[Pipeline] }
[Pipeline] // stage
[Pipeline] echo
bitbucketUtilities global vars, env: org.jenkinsci.plugins.workflow.cps.EnvActionImpl@75f03f42
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: java.lang.Class.notifyBuildFail() is applicable for argument types: (java.lang.String, java.lang.String) values: [Exception No signature of method: java.lang.Class.notifyBuildStart() is applicable for argument types: (java.lang.String, java.lang.String) values: [Build 44 started at 20190301-0810, Component Pipeline] in build 44, ...]
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:153)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:155)
    at org.kohsuke.groovy.sandbox.impl.Checker.checkedCall(Checker.java:159)
    at org.kohsuke.groovy.sandbox.impl.Checker$checkedCall.callStatic(Unknown Source)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallStatic(CallSiteArray.java:56)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callStatic(AbstractCallSite.java:194)
    at bitbucketUtilities.notifyBuildFail(bitbucketUtilities.groovy:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
    at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
    at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
    at org.codehaus.groovy.runtime.callsite.PogoMetaClassSite.call(PogoMetaClassSite.java:42)
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
    at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:157)
    at org.kohsuke.groovy.sandbox.GroovyInterceptor.onMethodCall(GroovyInterceptor.java:23)
    at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:155)
    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 componentPipeline.call(file:/var/jenkins_home/jobs/TDE_component_Current_Release/jobs/AlfaClient/branches/integrati.g220hfrp5s3u.y-handler/builds/44/libs/jenkins-shared-pipelines/vars/componentPipeline.groovy:306)
    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.GeneratedMethodAccessor617.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.LocalVariableBlock$LocalVariable.get(LocalVariableBlock.java:39)
    at com.cloudbees.groovy.cps.LValueBlock$GetAdapter.receive(LValueBlock.java:30)
    at com.cloudbees.groovy.cps.impl.LocalVariableBlock.evalLValue(LocalVariableBlock.java:28)
    at com.cloudbees.groovy.cps.LValueBlock$BlockImpl.eval(LValueBlock.java:55)
    at com.cloudbees.groovy.cps.LValueBlock.eval(LValueBlock.java:16)
    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:182)
    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


Reinhold Füreder

unread,
Mar 1, 2019, 3:20:09 AM3/1/19
to jenkins...@googlegroups.com

Hi,

 

a naive quick guess is that you are using too much groovy, but Jenkins pipeline code is -- well -- not fully groovy…

 

=> Maybe try to replace the fields like:

         @Field final BitbucketBuildOperationsHandler bitbucketUtilities = new BitbucketBuildOperationsHandler(this,env)

… in “bitbucketUtilities.groovy” with explicitly instantiating it in each method, e.g.:

@NonCPS
def notifyBuildFail(String message, String displayName) {
 
    //Remove
    println "bitbucketUtilities global vars, env: "+env
 
    validateCall(this, message, displayName)
 
    BitbucketBuildOperationsHandler bitbucketUtilities = new BitbucketBuildOperationsHandler(this,env)
    bitbucketUtilities.notifyBuildFail(message, displayName)
}

 

Please also note that in @NonCPS annotated methods you may not call pipeline steps AFAIK, “echo” step being a bit of an exception maybe?

 

HTH Reinhold

--
You received this message because you are subscribed to the Google Groups "Jenkins Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-use...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-users/ea38ce30-3c47-4797-afba-de3c0fcca930%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Kaliyug Antagonist

unread,
Mar 1, 2019, 3:31:47 AM3/1/19
to Jenkins Users
Instantiating every time works well, I had tried that earlier but that isn't the way I wish to go :(
Reply all
Reply to author
Forward
0 new messages