readYaml读取存在的deploy.placement路径返回null问题咨询
问题排查:Jenkins解析YAML时嵌套路径返回null的问题
问题场景
我有一个Docker Compose YAML文件:
version: '3.9' services: test_service: image: 10.3.0.4:5000/test_service:latest hostname: test_service stop_grace_period: 5m deploy: placement: constraints: - node.labels.worker == true
同时有一段Jenkinsfile代码用于解析该YAML:
steps{ script{ def my_yml = readYaml file: "docker-compose.yml" def req = '' def req_list = ["stop_grace_period", "deploy.placement"] for (item in req_list) { echo "${item}" req = my_yml.services."${MICROSERVICE}"."${item}" if (req == null) { echo "Fail" } } } }
问题:解析stop_grace_period时能正常获取值,但解析deploy.placement时返回null,尽管该路径在YAML中存在。
原因分析
Jenkins的readYaml步骤会将YAML解析为嵌套的Groovy Map对象,而非支持点号直接访问的扁平化结构。当你用"deploy.placement"作为键名时,Groovy会尝试在my_yml.services."${MICROSERVICE}"这个Map里查找键名为字符串"deploy.placement"的条目,而非先访问deploy子Map再读取其中的placement键,自然找不到对应值,返回null。
而stop_grace_period是一级键,直接用字符串键名访问就能命中,因此可以正常工作。
解决方法
有两种可行的处理方式:
方法1:拆分嵌套路径,逐层访问Map
将嵌套路径拆分为多级键,依次访问Map的层级:
steps{ script{ def my_yml = readYaml file: "docker-compose.yml" def service_config = my_yml.services."${MICROSERVICE}" // 处理stop_grace_period def stop_grace = service_config.stop_grace_period if (stop_grace == null) { echo "stop_grace_period Fail" } // 处理deploy.placement,用安全导航运算符避免空指针 def placement = service_config?.deploy?.placement if (placement == null) { echo "deploy.placement Fail" } } }
其中?.是安全导航运算符,可避免中间某一级为null时抛出空指针异常。
方法2:编写通用工具函数解析点分隔路径
如果需要批量处理多个点分隔的路径,可以编写工具函数递归解析嵌套Map:
steps{ script{ def my_yml = readYaml file: "docker-compose.yml" def service_config = my_yml.services."${MICROSERVICE}" // 定义解析点分隔路径的工具函数 def getNestedValue(Map map, String path) { def keys = path.split("\\.") def current = map for (key in keys) { if (current == null || !(current instanceof Map)) { return null } current = current[key] } return current } def req_list = ["stop_grace_period", "deploy.placement"] for (item in req_list) { echo "${item}" def req = getNestedValue(service_config, item) if (req == null) { echo "Fail" } } } }
该函数会将路径按点拆分,逐层遍历Map,最终返回对应值,适配批量处理需求。
内容的提问来源于stack exchange,提问作者BionicHamster
相关产品推荐
相关产品推荐

