You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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()
}

关键修改点说明

  1. 转换属性为普通类型:将device.@name、device.@time通过toString()转成String,避免持有原始的Attributes对象
  2. 局部变量收集结果:用局部列表slackMessages存储消息,代替直接修改外部的msgToSlack——外部变量更容易被Jenkins的CPS机制捕获并尝试序列化
  3. 确保返回值是可序列化类型:最终返回的是普通String,完全符合Jenkins的序列化要求

额外注意事项

  • @NonCPS方法内尽量不要保留任何XmlSlurper返回的对象(比如Node、NodeChild、Attributes),所有需要的数据都要提前提取成普通类型
  • 如果需要给Slack发送多条消息,可以用slackMessages.join('\n')拼接成一个字符串返回,更适合Slack的消息格式

内容的提问来源于stack exchange,提问作者jello

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:42:16