Jenkins流水线使用groovy.json.JsonBuilder报序列化异常的解决咨询
Jenkins流水线使用groovy.json.JsonBuilder报序列化异常的解决咨询
嗨,这个问题我之前也碰到过!核心原因是Jenkins流水线的CPS执行模型要求所有在流水线流程中传递的对象必须是可序列化的,而groovy.json.JsonBuilder类本身并没有实现序列化接口,所以当流水线尝试暂停/恢复执行时,就会抛出NotSerializableException。而Scriptler是直接运行普通Groovy脚本,没有这个序列化限制,所以代码能正常工作。
给你两个可行的解决办法:
方法一:改用JsonOutput直接构建JSON(推荐)
JsonOutput的方法会直接返回字符串(天然可序列化),完全适配流水线的执行环境,而且写法也很简洁:
def vars = ["a": 1,"b": 2,"c": 3,"d": 4] // 先构建对应的Map结构,和你想要的JSON结构一致 def jsonStructure = [ "file": [ "sample": vars ] ] // 转成格式化的JSON字符串 def prettyJson = groovy.json.JsonOutput.prettyPrint(groovy.json.JsonOutput.toJson(jsonStructure)) // 推荐用Jenkins内置的writeFile步骤写入文件 // 注意:如果你的流水线在agent节点上执行,writeFile会操作agent的文件系统,而new File()会操作master的,按需选择 writeFile(file: '/tmp/sample.json', text: prettyJson)
方法二:用@NonCPS注解隔离JsonBuilder操作
如果一定要保留JsonBuilder的写法,可以把相关逻辑放在被@NonCPS修饰的方法里。这个注解会告诉Jenkins不要对该方法内的代码进行CPS序列化处理,但要注意:@NonCPS方法里不能引用流水线的CPS变量(比如流水线参数、步骤返回的特殊对象),而且返回值必须是可序列化的类型(比如字符串):
def vars = ["a": 1,"b": 2,"c": 3,"d": 4] @NonCPS def buildJsonWithBuilder(varsMap) { def json = new groovy.json.JsonBuilder() json "file": [ "sample": varsMap ] return groovy.json.JsonOutput.prettyPrint(json.toString()) } def prettyJson = buildJsonWithBuilder(vars) writeFile(file: '/tmp/sample.json', text: prettyJson)
另外提醒一下:尽量避免在流水线里直接用new File(),除非你明确要操作Jenkins master的文件系统。如果流水线是在agent节点上运行的,用writeFile步骤才会把文件写到agent的对应路径里。
备注:内容来源于stack exchange,提问作者Alfred Hitchkock
相关产品推荐
相关产品推荐

