Jenkins流水线Groovy find操作符抛出NotSerializableException问题
解决Jenkins流水线Groovy正则匹配的序列化异常与构件下载问题
核心问题分析
报错java.io.NotSerializableException: java.util.regex.Matcher的本质是:Jenkins流水线的CPS执行模式要求所有变量可序列化,而java.util.regex.Matcher对象本身不支持序列化。老Jenkins实例可能因版本较低、CPS序列化策略宽松,或流水线未触发阶段间挂起/恢复(无需序列化变量)而正常运行;新实例的CPS机制更严格,触发了序列化检查导致报错。
同时第二个包下载失败,大概率和正则分组索引使用错误、或匹配结果未正确提取有关。
解决方案步骤
1. 替换不可序列化的Matcher对象,提取可序列化的匹配结果
不要直接将Matcher赋值给变量,而是提取匹配后的分组到字符串变量中,确保变量可序列化:
stage('Get build artifacts') { def buildVersion = params.BUILD_VERSION // 定义正则并执行匹配 def matcher = buildVersion =~ /^.*-b(\d*)-(.*)$/ // 先验证匹配是否成功,避免空指针 if (!matcher.matches()) { error "BUILD_VERSION格式错误,预期格式如1.0.0-b1-master,当前值:${buildVersion}" } // 提取分组到可序列化的字符串变量 def buildNum = matcher.group(1) // 对应版本号中的"1"(示例1.0.0-b1-master) def branchName = matcher.group(2) // 对应版本号中的"master"
2. 修正构件下载URL的构造逻辑
使用Groovy字符串插值替代字符串拼接,更简洁且不易出错,同时检查分组顺序是否符合目标URL的路径要求:
// 构造下载命令,根据实际路径调整分组顺序 def pkg1Url = "https://mywebsite/${branchName}/${buildNum}/pkg1-${buildVersion}.tar.gz" def pkg2Url = "https://mywebsite/${branchName}/${buildNum}/pkg2-${buildVersion}.tar.gz" // 执行wget命令(建议使用sh步骤的script参数) sh """ wget ${pkg1Url} wget ${pkg2Url} """ }
3. 排查新老Jenkins实例差异
- 检查Jenkins版本:新实例可能使用了更高版本的Workflow CPS插件,序列化验证更严格,需确保代码符合序列化要求。
- 检查流水线配置:新实例是否开启了
Preserve Stashes等需要序列化变量的功能,导致触发序列化检查。
关键注意事项
- 所有在流水线阶段间传递的变量必须是可序列化类型(如String、List、Map等),避免持有Matcher、InputStream等不可序列化对象。
- 正则匹配后务必先验证
matches()或find()结果,防止因版本号格式错误导致后续代码抛出空指针异常。 - 使用Groovy的字符串插值(
${变量名})替代字符串拼接,减少语法错误概率。
内容的提问来源于stack exchange,提问作者deconya
相关产品推荐
相关产品推荐

