Jenkins 如何将一个类的所有方法动态添加到另一个类中

Jenkins 如何将一个类的所有方法动态添加到另一个类中,jenkins,reflection,groovy,jenkins-pipeline,Jenkins,Reflection,Groovy,Jenkins Pipeline,我在所有管道上隐式加载了一个,然后我的Jenkinsfile如下所示: new com.company.Pipeline()() package com.company private Utils() {} static def install(def instance) { def utils = new Utils() // Some extra check needed here I know, but it is not the problem now for (def

我在所有管道上隐式加载了一个,然后我的
Jenkinsfile
如下所示:

new com.company.Pipeline()()
package com.company

private Utils() {}

static def install(def instance) {
  def utils = new Utils()
  // Some extra check needed here I know, but it is not the problem now
  for (def method in (utils.metaClass.methods*.name as Set) - (instance.metaClass.methods*.name as Set)) {
    def closure = utils.&"$method"
    closure.delegate = instance
    instance.metaClass."$method" = closure
  }
}

def someMethod() {
  // here I want to use sh(), tool(), and other stuff freely.
}
然后,共享库在
src/com/company
目录下的
Pipeline.groovy
类下面有一些文件:

package com.company  

import static Utils.*

def call() {
  // some stuff here...
}
问题是,这种方式我必须静态声明所有方法,因此我失去了上下文,没有
管道
类”实例,就无法轻松访问jenkins的方法。如您所见,他们将
传递给方法
mvn

考虑到避免这种情况,我想知道如何通过调用
Utils来动态地将所有方法添加为闭包。安装this
而不是使用
import static Utils.*
,那么我的
Utils.groovy类似于:

new com.company.Pipeline()()
package com.company

private Utils() {}

static def install(def instance) {
  def utils = new Utils()
  // Some extra check needed here I know, but it is not the problem now
  for (def method in (utils.metaClass.methods*.name as Set) - (instance.metaClass.methods*.name as Set)) {
    def closure = utils.&"$method"
    closure.delegate = instance
    instance.metaClass."$method" = closure
  }
}

def someMethod() {
  // here I want to use sh(), tool(), and other stuff freely.
}
但是它会引发一个
GStringImpl
不能转换为
String
的错误,我相信
&
不适用于变量,我如何将方法转换为在变量上具有方法名称的闭包?我最喜欢的是一个实例,如果有可能把它变成一个实例,也许问题可以解决,但每当我搜索groovy的方法到闭包转换时,我就找到了
&
解决方案


如果我使用
instance.metaClass.someMethod=utils.&someMethod
它确实可以工作,但我希望它是动态的,因为我添加了新方法,而不需要担心共享它。

有一种方法可以动态地完成它。Notation
utils.&someMethod
返回一个可以简单地用构造函数实例化的对象:

MethodClosure(Object owner, String method)
考虑以下示例:

class Utils {
    def foo() {
        println "Hello, Foo!"
    }
    def bar() {
        println "Hello, Bar!"
    }
}

class Consumer {
}

def instance = new Consumer()
def utils = new Utils()

(utils.metaClass.methods*.name - instance.metaClass.methods*.name).each { method ->
    def closure = new MethodClosure(utils, method)
    closure.delegate = instance
    instance.metaClass."$method" = closure
}

instance.foo() // Prints "Hello, Foo!"
instance.bar() // Prints "Hello, Bar!"

在本例中,我使用
def closure=newmethodclosure(utils,method)
获取对象方法引用,然后将此方法添加到
实例
对象。我希望它能帮上忙。

很好,它很有效,只是对于寄存器,我没有使用每个寄存器,因为詹金斯抱怨它不能序列化,但这解决了问题,谢谢。@TiagoPimenta很酷,很高兴我能帮到你:)