Jenkinsfile中循环Hashmap并传递key到shell/powershell/bat不生效问题
问题原因
Jenkins Pipeline 底层依赖序列化机制持久化运行时状态,用于支持任务暂停、重启、节点调度等能力,所有Pipeline步骤(如示例中的sh、echo)执行时,Jenkins都会尝试序列化当前作用域内的所有变量。
你遍历Map时拿到的defaults是LinkedHashMap$Entry类型对象,该类本身没有实现Java序列化接口,调用sh步骤时序列化失败就抛出了对应的异常。而遍历数组时拿到的是字符串类型,本身是可序列化的,所以不会触发报错。
解决方案
以下是两种常用的兼容方案:
方案1:直接遍历Map的键集合(无需用到value时首选)
直接遍历keySet()拿到的都是可序列化的字符串,完全避开不可序列化的Entry对象,修改循环逻辑如下:
echo "======started next HashMAP loop===========" // 直接遍历key集合,循环变量是字符串类型,可序列化 for(test in test2.keySet()){ echo "before shell====> ${test}" status = sh(returnStdout: true, script: """ echo "${test}" """).trim() // 如果需要取值直接用 test2[test] 即可 def currentValue = test2[test] }
方案2:提前把Map转换为可序列化的键值对列表(需同时用到key和value时使用)
先用collect方法把Map转换为普通的可序列化列表,每个元素是包含key、value的简单Map,再遍历该列表:
echo "======started next HashMAP loop===========" // 提前转为可序列化的列表 def test2List = test2.collect {[ key: it.key, value: it.value ]} for(entry in test2List){ def test = entry.key def currentValue = entry.value echo "before shell====> ${test}, value: ${currentValue}" status = sh(returnStdout: true, script: """ echo "${test}" """).trim() }
内容的提问来源于stack exchange,提问作者Ganesh
相关产品推荐
相关产品推荐

