Jenkins/groovy:如何用 null 漂亮地打印 net.sf.json.JSONObject?
Jenkins/groovy: How to pretty-print a net.sf.json.JSONObject with null?
在 Jenkins 管道上工作时,我观察到当我在 net.sf.json.JSONObject
上使用 JsonOutput.toJson()
时看起来像无限递归导致堆栈溢出,该 net.sf.json.JSONObject
吞噬了包含 null 的 JSON 字符串。
以下最少的代码演示了该问题:
// Jenkinsfile
@Library('libs@dev') libs
import groovy.json.JsonOutput
pipeline {
agent any
stages {
stage( "json" ) {
steps {
script {
my_lib.to_json_handbuilt_linkedhashmap()
my_lib.to_json_readjson()
my_lib.to_json_readjson_as_linkedhashmap()
}
}
}
}
}
// vars/my_lib.groovy
import groovy.json.JsonOutput
def asMap(j) {
return j as LinkedHashMap
}
// This function is successful.
def to_json_handbuilt_linkedhashmap() {
def d = [:]
d.issues = null
echo "---- handmade LinkedHashMap ----"
echo "d ${d}"
echo "d.getClass() ${d.getClass()}"
echo "JsonOutput.toJson(d) ${JsonOutput.toJson(d)}"
}
// This function fails from infinite recursion causing a stack overflow.
def to_json_readjson() {
def d = readJSON(text: '{ "issues" : null }')
echo "---- readJSON ----"
echo "d ${d}"
echo "d.getClass() ${d.getClass()}"
echo "JsonOutput.toJson(d) ${JsonOutput.toJson(d)}"
}
// This function also fails from infinite recursion causing a stack overflow.
def to_json_readjson_as_linkedhashmap() {
def d = asMap(readJSON(text: '{ "issues" : null }'))
echo "---- readJSON -> asMap ----"
echo "d ${d}"
echo "d.getClass() ${d.getClass()}"
echo "JsonOutput.toJson(d) ${JsonOutput.toJson(d)}"
}
在上面的代码中,当使用 readJSON(text: '{ "issues" : null }')
返回的 net.sf.json.JSONObject
调用 JsonOutput.toJson()
时,to_json_readjson()
失败并出现堆栈溢出。
Jenkins 控制台输出在此 post.
的末尾
在 to_json_handbuilt_linkedhashmap()
中 JsonOutput.toJson()
使用手工制作的 LinkedHashMap
调用时成功,相当于 { "issues" : null }
.
最后,在 to_json_readjson_as_linkedhashmap()
中,当使用从 net.sf.json.JSONObject
创建的 LinkedHashMap
调用时,JsonOutput.toJson()
再次失败并出现堆栈溢出。
问题:
谁能解释一下当 readJSON()
and/or JsonOutput.toJson()
与具有 null
的 JSON 字符串一起使用时导致堆栈溢出的原因?
因为我手工制作的LinkedHashMap
用JsonOutput.toJson()
成功了,我以为问题是通过了JsonOutput.toJson()
一个net.sf.json.JSONObject
.
但我认为该理论已被排除,因为在 to_json_readjson_as_linkedhashmap()
中,我给 JsonOutput.toJson()
一个 LinkedHashMap
,尽管它是从 net.sf.json.JSONObject
.
创建的
问题似乎是我未能掌握的 readJSON()
and/or JsonOutput.toJson()
的某种组合。
我试过了,但是已经放弃尝试使用 JsonSlurper
,因为 I'm unable to even create an instance of one.
可能显示无限递归的(截断的)堆栈溢出错误:
Posting build status of FAILED to bitbucket.company.comjava.lang.WhosebugError
at java.io.PrintStream.flush(PrintStream.java:338)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:297)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at java.util.logging.StreamHandler.flush(StreamHandler.java:259)
at java.util.logging.ConsoleHandler.publish(ConsoleHandler.java:117)
at java.util.logging.Logger.log(Logger.java:738)
at java.util.logging.Logger.doLog(Logger.java:765)
at java.util.logging.Logger.throwing(Logger.java:1447)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.getProperties(DefaultGroovyMethods.java:391)
at groovy.json.JsonOutput.getObjectProperties(JsonOutput.java:327)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:320)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
您能否通过使用 readJSON
的 returnPojo: true
参数来回避这个紧迫的问题,从而更快地解决您的整体任务?
获取普通的旧 null
对象而不是 net.sf.json.JSONNull 对象今天确实帮助了我,尽管我的问题涉及生成 CSV 而不是使用 JsonOutput。
在 Jenkins 管道上工作时,我观察到当我在 net.sf.json.JSONObject
上使用 JsonOutput.toJson()
时看起来像无限递归导致堆栈溢出,该 net.sf.json.JSONObject
吞噬了包含 null 的 JSON 字符串。
以下最少的代码演示了该问题:
// Jenkinsfile
@Library('libs@dev') libs
import groovy.json.JsonOutput
pipeline {
agent any
stages {
stage( "json" ) {
steps {
script {
my_lib.to_json_handbuilt_linkedhashmap()
my_lib.to_json_readjson()
my_lib.to_json_readjson_as_linkedhashmap()
}
}
}
}
}
// vars/my_lib.groovy
import groovy.json.JsonOutput
def asMap(j) {
return j as LinkedHashMap
}
// This function is successful.
def to_json_handbuilt_linkedhashmap() {
def d = [:]
d.issues = null
echo "---- handmade LinkedHashMap ----"
echo "d ${d}"
echo "d.getClass() ${d.getClass()}"
echo "JsonOutput.toJson(d) ${JsonOutput.toJson(d)}"
}
// This function fails from infinite recursion causing a stack overflow.
def to_json_readjson() {
def d = readJSON(text: '{ "issues" : null }')
echo "---- readJSON ----"
echo "d ${d}"
echo "d.getClass() ${d.getClass()}"
echo "JsonOutput.toJson(d) ${JsonOutput.toJson(d)}"
}
// This function also fails from infinite recursion causing a stack overflow.
def to_json_readjson_as_linkedhashmap() {
def d = asMap(readJSON(text: '{ "issues" : null }'))
echo "---- readJSON -> asMap ----"
echo "d ${d}"
echo "d.getClass() ${d.getClass()}"
echo "JsonOutput.toJson(d) ${JsonOutput.toJson(d)}"
}
在上面的代码中,当使用 readJSON(text: '{ "issues" : null }')
返回的 net.sf.json.JSONObject
调用 JsonOutput.toJson()
时,to_json_readjson()
失败并出现堆栈溢出。
Jenkins 控制台输出在此 post.
在 to_json_handbuilt_linkedhashmap()
中 JsonOutput.toJson()
使用手工制作的 LinkedHashMap
调用时成功,相当于 { "issues" : null }
.
最后,在 to_json_readjson_as_linkedhashmap()
中,当使用从 net.sf.json.JSONObject
创建的 LinkedHashMap
调用时,JsonOutput.toJson()
再次失败并出现堆栈溢出。
问题:
谁能解释一下当 readJSON()
and/or JsonOutput.toJson()
与具有 null
的 JSON 字符串一起使用时导致堆栈溢出的原因?
因为我手工制作的LinkedHashMap
用JsonOutput.toJson()
成功了,我以为问题是通过了JsonOutput.toJson()
一个net.sf.json.JSONObject
.
但我认为该理论已被排除,因为在 to_json_readjson_as_linkedhashmap()
中,我给 JsonOutput.toJson()
一个 LinkedHashMap
,尽管它是从 net.sf.json.JSONObject
.
创建的
问题似乎是我未能掌握的 readJSON()
and/or JsonOutput.toJson()
的某种组合。
我试过了,但是已经放弃尝试使用 JsonSlurper
,因为 I'm unable to even create an instance of one.
可能显示无限递归的(截断的)堆栈溢出错误:
Posting build status of FAILED to bitbucket.company.comjava.lang.WhosebugError
at java.io.PrintStream.flush(PrintStream.java:338)
at sun.nio.cs.StreamEncoder.implFlush(StreamEncoder.java:297)
at sun.nio.cs.StreamEncoder.flush(StreamEncoder.java:141)
at java.io.OutputStreamWriter.flush(OutputStreamWriter.java:229)
at java.util.logging.StreamHandler.flush(StreamHandler.java:259)
at java.util.logging.ConsoleHandler.publish(ConsoleHandler.java:117)
at java.util.logging.Logger.log(Logger.java:738)
at java.util.logging.Logger.doLog(Logger.java:765)
at java.util.logging.Logger.throwing(Logger.java:1447)
at org.codehaus.groovy.runtime.DefaultGroovyMethods.getProperties(DefaultGroovyMethods.java:391)
at groovy.json.JsonOutput.getObjectProperties(JsonOutput.java:327)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:320)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
at groovy.json.JsonOutput.writeMap(JsonOutput.java:458)
at groovy.json.JsonOutput.writeObject(JsonOutput.java:321)
您能否通过使用 readJSON
的 returnPojo: true
参数来回避这个紧迫的问题,从而更快地解决您的整体任务?
获取普通的旧 null
对象而不是 net.sf.json.JSONNull 对象今天确实帮助了我,尽管我的问题涉及生成 CSV 而不是使用 JsonOutput。