为何Jenkins readYaml流水线工具步骤忽略YAML重复键?
我在使用Jenkins流水线的readYaml步骤读取以下YAML文件时:
key1: subkey1: val1 key2: subkey2: val2 key2: subkey2: val3
发现该步骤会自动处理重复的key2,直接保留最后一个值(subkey2: val3),但既不抛出异常也没有任何提示。查看readYaml插件的源代码后,没找到相关的重复键处理配置。已知该插件依赖SnakeYAML库,而SnakeYAML默认是允许重复键的,如果Jenkins没有修改LoaderOptions的配置,为什么重复键会被"忽略"(实际是被覆盖)?
核心原因:SnakeYAML的默认重复键处理逻辑是"覆盖"而非"报错"
你提到的"忽略"其实是SnakeYAML的默认行为——当解析遇到重复键时,后续的键值对会直接覆盖前面的内容,而不是抛出异常或者保留所有条目。
Jenkins Pipeline Utility Steps插件的readYaml步骤,确实直接使用了SnakeYAML的默认Loader实现,没有额外配置重复键的校验规则。SnakeYAML默认的LoaderOptions中,setAllowDuplicateKeys(true)是默认开启的,但这个配置的含义是"允许重复键存在",而允许存在后的处理逻辑就是用后面的值覆盖前面的,并非保留所有重复项或报错。
验证逻辑:SnakeYAML的默认解析行为
如果直接用原生SnakeYAML解析你提供的YAML,得到的Map结果里key2对应的value就是最后一个subkey2: val3,和JenkinsreadYaml的结果一致。这完全符合SnakeYAML的默认处理规则,和Jenkins是否修改配置无关——因为默认规则就是覆盖。
如何让重复键抛出异常(可选)
如果需要在遇到重复键时触发报错,需要手动配置SnakeYAML的LoaderOptions,设置setAllowDuplicateKeys(false),但Jenkins的readYaml步骤目前没有暴露这个配置项,所以只能通过自定义流水线代码来实现(比如自己编写Groovy代码调用SnakeYAML并配置该选项)。
内容的提问来源于stack exchange,提问作者Saikat

