Jenkins Pipeline 抛出 ProxyException“预期调用 Device.<init> 但最终捕获 Device.getIP”

김현준*_*김현준 4 groovy jenkins jenkins-groovy

我在 Jenkins 管道中创建了一个这样的类。

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
Run Code Online (Sandbox Code Playgroud)

当我在“Groovy Web 控制台”( https://groovyconsole.appspot.com/ ) 中尝试它时效果很好,但是当我在 Jenkins 中运行此脚本时,会出现以下错误。

[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
Run Code Online (Sandbox Code Playgroud)

剧本有什么问题吗?

Szy*_*iak 7

底层 Jenkins 管道引擎将您的 Groovy 代码转换为groovy-cps兼容代码。它有几个限制,其中之一是getIP从非 CPS 转换的方法(构造函数方法)调用 CPS 转换的方法(在您的情况下)。

这是描述此限制的文档页面。

构造函数

有时,用户可能会尝试使用 CPS 转换的代码,例如 Pipeline 脚本中构造函数内的 Pipeline 步骤。不幸的是,通过 Groovy 中的运算符构造对象new不能进行 CPS 转换 ( JENKINS-26313 ),因此这不起作用。

getIP您可以从构造函数中删除对方法的调用,也可以使用注释getIP来注释方法@NonCPS