加载外部Groovy类后调用Jenkins Pipeline函数报错问题
问题解决:外部Groovy类调用Jenkins Pipeline方法报MissingMethodException
核心原因
Jenkins Pipeline的dir()、checkout()等DSL方法是绑定在当前Pipeline脚本的上下文(Script实例)中的,通过readTrusted()加载的外部Groovy类默认没有这个上下文,因此无法直接调用这些方法。
解决方案
1. 传递Pipeline上下文到外部类
在外部类中保存Pipeline上下文实例,通过上下文调用DSL方法:
外部类文件(class_file.groovy)
class GitOps { // 保存Pipeline上下文 def pipelineContext // 构造方法接收上下文 GitOps(context) { this.pipelineContext = context } def performCheckout() { // 通过上下文调用checkout方法 pipelineContext.checkout([ $class: 'GitSCM', branches: [[name: 'master']], extensions: [[$class: 'LocalBranch']] // 其他参数... ]) } def useDir() { // 通过上下文调用dir方法 pipelineContext.dir('target') { // 执行目录内操作 } } }
Pipeline脚本中调用
// 加载并初始化类,传入当前Pipeline上下文(this) def gitOpsClass = evaluate(readTrusted('class_file.groovy')) def gitOps = new gitOpsClass(this) // 调用类方法 gitOps.performCheckout() gitOps.useDir()
2. 传递Pipeline方法作为闭包
如果只需要个别方法,也可以直接把DSL方法作为闭包传递给外部类:
外部类方法修改
class GitOps { def performCheckout(def checkoutClosure) { checkoutClosure.call([ $class: 'GitSCM', branches: [[name: 'master']], extensions: [[$class: 'LocalBranch']] ]) } }
Pipeline脚本调用
def gitOps = new GitOps() // 传递checkout方法的闭包引用 gitOps.performCheckout(this.&checkout)
3. 让外部类继承Script类(不推荐)
将外部类继承Groovy的Script类,使其能直接使用Pipeline上下文的绑定,但这种方式会增加耦合性:
外部类修改
class GitOps extends Script { def run() { checkout([ $class: 'GitSCM', branches: [[name: 'master']], extensions: [[$class: 'LocalBranch']] ]) } }
Pipeline脚本调用
def gitOps = evaluate(readTrusted('class_file.groovy')).newInstance(binding) gitOps.run()
内容的提问来源于stack exchange,提问作者Tsahi Elkayam
相关产品推荐
相关产品推荐

