Groovy 共享库类成员函数中的 println() 为什么没有出现在 Jenkins 控制台日志中?

问题描述 投票:0回答:1

这个问题来自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()

共享库设置为名为“foo”的全局管道库:

共享库实现一个全局变量:

// 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
注释的各种组合——这些似乎都不会影响上述行为.

jenkins groovy jenkins-pipeline shared-libraries
1个回答
0
投票

我通过向墙上扔意大利面条并看到卡住的东西发现了这一点。

从这样的 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()")
  }
}

即作为所问问题的答案,有两件事似乎是必要的:

  1. 必须为共享库类提供并使用
    steps
    .
  2. 的句柄
  3. 共享库类必须使用
    steps.echo
    ,而不是
    steps.println

Jenkins/Groovy 继续慢慢地让我发疯。

© www.soinside.com 2019 - 2024. All rights reserved.