Jenkins Pipeline throws ProxyException "expected to call Device.<init> but wound up catching Device.getIP"

Viewed 4990

I create a class in Jenkins pipeline like this.

class Device
{
    def ip = null
    def context
    
    def getIP(devName) 
    {
        return "aaa.bbb.ccc.ddd"
    }

    Device(context, devName, devType)
    {
        print("[DEBUG] ctor device")
        ip = getIP(devName)
        this.context = context
        print(ip)
    }
}


ap = new Device(this, "DEV", "TYPE")
print ap.ip

It works well when I try it in the 'Groovy web console' (https://groovyconsole.appspot.com/) But when I run this script in Jenkins, the following error occurs.

[Pipeline] Start of Pipeline

expected to call Device.<init> but wound up catching Device.getIP; see: https://jenkins.io/redirect/pipeline-cps-method-mismatches/

[Pipeline] End of Pipeline

hudson.remoting.ProxyException: CpsCallableInvocation{methodName=getIP, call=com.cloudbees.groovy.cps.impl.CpsFunction@20fd33e6, receiver=Device@57905ade, arguments=[DEV]}

Finished: FAILURE

What's wrong with the script?

1 Answers

Underlying Jenkins pipeline engine transforms your Groovy code to the groovy-cps compatible one. It comes with several limitations, and one of them is calling CPS-transformed method (getIP in your case) from the method that is not CPS-transformed (constructor method.)

Here is the documentation page that describes this limitation.

Constructors

Occasionally, users may attempt to use CPS-transformed code such as Pipeline steps inside of a constructor in a Pipeline script. Unfortunately, the construction of objects via the new operator in Groovy is not something that can be CPS-transformed (JENKINS-26313), and so this will not work.

You can either remove the call to the getIP method from the constructor, or you can annotate getIP method with @NonCPS annotation.

Related