(错误)管道 Jenkins,在循环 + 序列化 JSON 中调用 SH



我不明白为什么会发生错误:

stage('name') {
steps {
script {
def jsonObj = new JsonSlurper().parseText( env.work_servers )
for(item in jsonObj){
cmd("my command --param1=${item.srv} --param2=${item.port}")
}
}
}
}

收到错误,错误堆栈 https://pastebin.com/V09ZXrif

即使您将 cmd 方法调用替换为 sh,也没有任何变化

如果您在没有循环的情况下调用命令,一切正常

stage('name') {
steps {
script {
def srv = "..."
def port = "..."
cmd("my command --param1=${srv} --param2=${port}")
srv = "..."
port = "..."
cmd("my command --param1=${srv} --param2=${port}")
}
}
}

这也有效

stage('name') {
steps {
script {
def jsonObj = new JsonSlurper().parseText( env.work_servers )
for(item in jsonObj){
echo item 
}
}
}
}
def cmd(command) {
result = ""
if (isUnix()) {
result = sh(
script: command,
returnStdout: true
).trim()
} else {
bat "chcp 65001n${command}"
}
return result
}

您会看到此问题,因为new JsonSlurper().parseText(text)返回类型groovy.json.internal.LazyMap的映射,该映射不可序列化。在阶段内运行的任何代码都必须对可序列化对象进行操作。(例外可以应用于用@NonCPS批注的提取方法。

此问题的解决方案很简单 - 将JsonSlurper替换为从parseText(text)方法返回HashMapJsonSlurperClassic

stage('name') {
steps {
script {
def jsonObj = new JsonSlurperClassic().parseText( env.work_servers )
for(item in jsonObj){
cmd("my command --param1=${item.srv} --param2=${item.port}")
}
}
}
}

或者,如果您需要继续使用JsonSlurper则可以将解析 JSON 并使用 JSON 对象执行任何操作的部分提取到单独的方法中,并使用@NonCPS对其进行注释。如果您的 JSON 很大并且使用LazyMap有意义,您可以考虑此替代选项。否则,切换到JsonSlurperClassic是解决问题的最佳方法。

最新更新