Jenkins中遇java.io.NotSerializableException错误求解决方向
解决Jenkins Groovy脚本的
NotSerializableException问题 我来帮你拆解这个序列化错误的根源,以及给出具体的修复方案:
问题核心原因
虽然你给方法加了@NonCPS注解,但你的代码里还是间接持有了不可序列化的对象:XmlSlurper返回的groovy.util.slurpersupport.Attributes(就是你代码里device.@name、device.@time这类属性对象)。Jenkins的CPS执行模式会尝试序列化所有上下文变量,哪怕在@NonCPS方法内,闭包中引用的原始XmlSlurper对象依然会被捕获,触发序列化失败。
具体修复步骤
核心思路是:把XmlSlurper解析的结果转换成普通的可序列化数据类型(比如String、Integer、List、Map),彻底切断和XmlSlurper不可序列化对象的关联。
修改后的代码示例:
@NonCPS String myFunction(){ def parsed = new XmlSlurper().parse("${workspace}/tmp/TESTS-myTest.xml") println "${parsed} is this" println "We found 0 errors" // 用局部列表收集消息,避免闭包直接修改外部变量 def slackMessages = [] parsed.testsuite.testcase.each { device -> // 把XmlSlurper的属性对象转成普通String/数值 def deviceName = device.@name.toString() def deviceTimeMinutes = (device.@time.toInteger())/60 def msg = "Name of phone is: ${deviceName} ran for ${deviceTimeMinutes} Minutes" println msg slackMessages.add(msg) } // 返回最后一条消息,或者根据需求拼接所有消息 return slackMessages.last().toString() }
关键修改点说明
- 转换属性为普通类型:将
device.@name、device.@time通过toString()转成String,避免持有原始的Attributes对象 - 局部变量收集结果:用局部列表
slackMessages存储消息,代替直接修改外部的msgToSlack——外部变量更容易被Jenkins的CPS机制捕获并尝试序列化 - 确保返回值是可序列化类型:最终返回的是普通String,完全符合Jenkins的序列化要求
额外注意事项
@NonCPS方法内尽量不要保留任何XmlSlurper返回的对象(比如Node、NodeChild、Attributes),所有需要的数据都要提前提取成普通类型- 如果需要给Slack发送多条消息,可以用
slackMessages.join('\n')拼接成一个字符串返回,更适合Slack的消息格式
内容的提问来源于stack exchange,提问作者jello
相关产品推荐
相关产品推荐

