【发布时间】:2017-05-31 23:03:15
【问题描述】:
我有一个带有以下文件的 Jenkins shared library:
vars/testlib.groovy
def foo() {
echo 'foo'
}
def bar(body) {
body.delegate = [:]
body.resolveStrategy = Closure.DELEGATE_FIRST
body()
}
还有一个流水线脚本如下:
Jenkins 文件
library 'testlib@master'
testlib.foo()
testlib.bar {
testlib.foo()
}
我得到以下输出:
[Pipeline] echo
foo
[Pipeline] End of Pipeline
java.lang.NullPointerException: Cannot invoke method foo() on null object
由于某种原因,传递给testlib.bar 的闭包不再看到testlib。只有当决议策略有利于代表时才会发生这种情况;如果我使用 OWNER_ONLY 或 OWNER_FIRST 它可以工作。如果我在委托中提供testlib,它也可以工作,无论是通过在地图中设置它还是通过设置body.delegate = body.owner,如果我通过在闭包中引用owner.testlib.foo来避免解决方案,它也可以工作。此外,这只发生在库代码中;如果我只是在 Jenkinsfile 中创建一个测试类,它就可以正常工作。
似乎解决策略是检查委托,而委托不提供该属性,它会立即失败,而无需费心接下来检查所有者。我做错了吗?
【问题讨论】:
-
我注意到一般来说,带有函数的 var 文件会让你在 Jenkins 管道及其单元测试中陷入一些黑暗的角落(无法解释和错误的行为)。我也必须使用明确的
this引用来解决其中一些问题(与owner相同,但this.foo()看起来比owner.foo()更干净)。
标签: jenkins groovy jenkins-pipeline