这个问题来自Why is this Groovy class static function not executed from its calling Jenkins pipeline?.
我有一个像这样设置的 Jenkins/groovy 共享库:
+- src # Groovy source files
| +- org
| +- company
| +- Stage.groovy # for org.company.Stage class
+- vars
+- func.groovy # for global var func()
共享库实现一个全局变量:
// vars/func.groovy
def func(d) {
println("func.groovy:func()")
}
...和类
Stage
具有成员函数 func
:
// src/org/company/Stage.groovy
package org.company;
class Stage implements Serializable {
def func(d) {
println("org.company.Stage.func()")
return 'hello, world!`
}
}
注意全局变量和类成员函数都做同样的事情:
println
一些静态字符串。
我的 Jenkins 管道同时调用全局变量和类成员函数:
// Jenkinsfile
@Library('foo@dev')
import org.company.Stage
pipeline {
agent any
stages {
stage('1') {
steps {
testLoadLib()
}
}
}
}
void testLoadLib() {
loadLibrary('foo@dev')
}
void loadLibrary(String libraryName) {
def lib = library(libraryName)
def d = [:]
func.func(d)
def myvar = new Stage()
def ret = myvar.func()
println(ret)
}
这个 Jenkins 流水线的输出是:
Only using first definition of library foo
[Pipeline] echo
func.groovy:func()
[Pipeline] echo
hello, world!
[Pipeline] }
[Pipeline] // stage
[Pipeline] }
[Pipeline] // withEnv
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
问题:为什么
println()
中的org.company.Stage.func()
没有反映在Jenkins控制台日志中,而全局变量println()
中的func.func()
却反映在Jenkins控制台日志中?org.company.Stage.func()
的返回值,很明显该函数正在执行......但它的功能是“瘫痪的” - 我不知道如何描述它......println
被静音...还有哪些其他功能受到损害?println()
语句的行为在调用全局变量和调用类函数之间会有所不同?
我已经尝试了
class Stage
与public class Stage
、def func(d)
与public def func(d)
、删除/保留implements Serializable
和@NonCPS
注释的各种组合——这些似乎都不会影响上述行为.
我通过向墙上扔意大利面条并看到卡住的东西发现了这一点。
从这样的 Jenkinsfile 开始:
// Jenkinsfile
@Library('foo@dev')
import org.company.Stage
...
def myvar = new Stage(steps)
myvar.func()
...这有效:
// src/org/company/Stage.groovy
package org.company;
class Stage {
def steps
Stage(steps) {this.steps = steps}
def func(d) {
steps.echo("org.company.Stage.func()")
}
}
这不工作:
// src/org/company/Stage.groovy
package org.company;
class Stage {
def steps
Stage(steps) {this.steps = steps}
def func(d) {
steps.println("org.company.Stage.func()")
}
}
即作为所问问题的答案,有两件事似乎是必要的:
steps
.steps.echo
,而不是steps.println
。Jenkins/Groovy 继续慢慢地让我发疯。