Jenkins Pipeline 中使用 JsonSlurper 报错:cannot find current thread

Jenkins Pipeline 中使用 JsonSlurper 报错:cannot find current thread

  • 🌟 背景
  • ⚠ 问题重现
  • 🧠 原因解析:CPS 与非 CPS 安全方法冲突
  • ✅ 解决方案一:使用 @NonCPS 注解(经典方案)
  • ✅ 解决方案二:使用 `readJSON` 步骤(推荐)
  • ✅ 解决方案三:完全在 `script {}` 中处理(适合小范围)
  • 🔁 最佳实践推荐
  • ❌ 避免的错误写法
  • 📌 总结

🌟 背景

在 Jenkins 声明式 Pipeline 中,有时我们需要解析一段 JSON 字符串,例如部署路径、构建参数等。在 Groovy 中,最常见的方式是使用 JsonSlurper

def jsonData = new groovy.json.JsonSlurper().parseText(myJsonText)

然而,在 Jenkins 中你很可能会遇到如下报错:

java.io.IOException: cannot find current thread

这类报错常常让人摸不着头脑。为什么在 Groovy 中正常工作的代码,在 Jenkins Pipeline 中却报错?


⚠ 问题重现

pipeline {agent anystages {stage('Parse JSON') {steps {script {def jsonText = '[{"src":"/a","dest":"/b"}]'def deployList = new groovy.json.JsonSlurper().parseText(jsonText) // 报错行}}}}
}

运行报错:

Cannot contact <node>: java.io.IOException: cannot find current thread

🧠 原因解析:CPS 与非 CPS 安全方法冲突

Jenkins Pipeline 基于 Groovy CPS(Continuation Passing Style)转换机制 实现“流水线可恢复性”。这意味着:

  • Pipeline 中的脚本会被 Jenkins 转换成 CPS 代码
  • CPS 会将执行状态保存到磁盘,以支持“中断恢复”、“断点续跑”
  • 然而,一些方法(如 JsonSlurper.parseText())不是 CPS 安全的,即不能被 Jenkins 正确序列化和恢复

✴ 为什么会报错?

JsonSlurper 会在底层调用 Thread.currentThread()、或使用 Java 原生 IO API,这在 CPS 上下文中是不被支持的操作。因此 Jenkins 抛出:

java.io.IOException: cannot find current thread

本质上,是 Jenkins 的 CPS 执行引擎无法“保存你执行的上下文状态”。


✅ 解决方案一:使用 @NonCPS 注解(经典方案)

将解析方法单独封装,并添加 @NonCPS 注解:

@NonCPS
def parseDeployPath(String jsonText) {try {if (jsonText == null || jsonText.trim() == "") {// 输入为空,返回空列表return []}def rawList = new groovy.json.JsonSlurper().parseText(jsonText)def simpleList = rawList.collect { item -> [src: item.src.toString(), dest: item.dest.toString()]}return simpleList} catch (Exception e) {println "❌ JSON 解析 deployPath 失败:${e.message}"return null}
}pipeline {agent anystages {stage('Parse') {steps {script {def json = '[{"src":"/a","dest":"/b"}]'def deployList = parseDeployPath(json)echo "Deploy List: ${deployList}"}}}}
}

为什么可行?

使用 @NonCPS 修饰的方法,不会被 Jenkins 的 CPS 引擎转换,因此可以使用原生 Groovy 方法,但代价是:

  • 无法使用 DSL(如 sh, echo 等)
  • 方法内不可访问 Pipeline 变量(如 env, params

✅ 解决方案二:使用 readJSON 步骤(推荐)

安装插件:Pipeline Utility Steps

pipeline {agent anystages {stage('Parse JSON safely') {steps {script {writeFile file: 'deploy.json', text: '[{"src":"/a","dest":"/b"}]'def deployList = readJSON file: 'deploy.json'deployList.each {echo "src: ${it.src}, dest: ${it.dest}"}}}}}
}

优势:

  • readJSON 是 Jenkins 官方提供的 DSL 级方法
  • 完全支持 流水线序列化和恢复
  • 不需要使用 @NonCPS

✅ 解决方案三:完全在 script {} 中处理(适合小范围)

虽然 JsonSlurper 本身不是 CPS 安全的,但在某些场景下,如果你在 script {} 中直接使用它,而没有调用嵌套函数,也能正常工作。

script {def json = '[{"src":"/a","dest":"/b"}]'def list = new groovy.json.JsonSlurper().parseText(json)list.each {echo "src: ${it.src}, dest: ${it.dest}"}
}

⚠ 注意:这种方式不一定在所有 Jenkins 环境中都安全,视具体版本而定。


🔁 最佳实践推荐

场景推荐方式
生产级流水线中解析 JSONreadJSON
工具方法、辅助转换@NonCPS
快速测试、数据调试script { JsonSlurper }

❌ 避免的错误写法

不要这样写:

def deployList = new groovy.json.JsonSlurper().parseText(params.jsonData)

或嵌套在函数中调用:

def parseIt() {return new JsonSlurper().parseText('...')
}

✅ 改为 @NonCPS 修饰 或使用 readJSON


📌 总结

Jenkins Pipeline 中,Groovy 方法并非都能直接使用。受限于 Jenkins 的 CPS 系统,很多涉及 IO、线程、状态不可序列化的操作会报错。面对 JsonSlurper 报错,推荐采用:

  • 首选:使用 Jenkins DSL 提供的 readJSON + writeFile
  • 通用:将 JSON 操作封装为 @NonCPS 方法
  • 调试:仅在 script {} 中临时使用 JsonSlurper

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/89574.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/89574.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go 语言循环语句详解

Go 语言循环语句详解 在编程语言中&#xff0c;循环语句是实现重复执行某些代码块的关键元素。Go 语言作为现代编程语言之一&#xff0c;提供了多种循环结构来满足不同的编程需求。本文将详细讲解 Go 语言中的循环语句&#xff0c;包括 for、while 和 goto 语句&#xff0c;帮助…

day30——零基础学嵌入式之进程间通信1.0

一、进程间通信7种方式1.传统的进程间通信方式&#xff08;1&#xff09;管道①无名管道&#xff1a;②有名管道&#xff1a;&#xff08;2&#xff09;③信号&#xff08;3&#xff09;system Ⅴ 》系统Ⅴ 进程间通信方式 inner Process Comunication④共享内存 &#xff…

408考研逐题详解:2010年第33题——网络体系结构

2010年第33题 下列选项中&#xff0c;不属于网络体系结构所描述的内容是&#xff08; &#xff09; A. 网络的层次 \qquad B. 每层使用的协议 \qquad C. 协议的内部实现细节 \qquad D. 每层必须完成的功能 解析 本题属于计算机网络基础知识的范畴&#xff0c;考查网络体系结构…

VR 远程系统的沉浸式协作体验​

在传统的远程协作中&#xff0c;团队成员往往通过二维的视频画面进行交流&#xff0c;这种方式虽然能实现基本的沟通&#xff0c;但缺乏真实感和互动性。而 VR 远程系统的出现&#xff0c;彻底改变了这一局面。戴上 VR 设备&#xff0c;员工们仿佛置身于同一个真实的办公室空间…

记录DataGrip 2025.1.3破解失败后,无法重启问题修复

记录DataGrip 2025.1.3破解失败后&#xff0c;无法重启问题修复安装过程复盘异常场景解决方式总结安装过程 在官网下载了最新版本2025.1.3。安装成功后&#xff0c;使用30天试用方式&#xff0c;打开datagrip。 复盘异常场景 网上搜索破解教程进行破解。找了一个需要现在ja…

私有服务器AI智能体搭建配置选择记录

在搭建私有服务器上的AI智能体时&#xff0c;需要从多个方面进行选择和规划&#xff0c;以确保系统性能、安全性、可扩展性等方面满足需求。1. 硬件选择 服务器配置&#xff1a; CPU&#xff1a;选择高性能多核CPU&#xff08;如Intel Xeon或AMD EPYC系列&#xff09;&#xff…

SDC Specical check setting的描述 - false path

在上一篇文中描述了SDC的基本语法&#xff0c;其中关于时序异常约束并没有进行详细的描述&#xff0c;但是在正常的设计中&#xff0c;一般这种异常的设置反而是需要特别关注的&#xff0c;主要包括&#xff1a;1. 虚假路径- false path不需要满足任何时序要求的路径&#xff1…

【Python练习】048. 编写一个函数,实现简单的命令行接口,接受用户输入并响应

048. 编写一个函数,实现简单的命令行接口,接受用户输入并响应 在 Python 中,可以通过 input() 函数创建一个简单的命令行接口,接受用户输入并根据输入内容进行响应。 示例代码 def simple_command_line_interface():"""实现一个简单的命令行接口,接受用…

软件工厂语境下的知识系统选型:兼顾合规性与集成深度

在过去几十年间&#xff0c;制造业从“工匠手作”迈向“工业流水线”&#xff0c;完成了生产效率的巨大飞跃。当软件开发也面临交付复杂性、合规要求与协作成本不断上升的现实&#xff0c;“软件工厂”的理念逐步兴起。 在这场“开发现代化”的转型中&#xff0c;知识管理被重新…

C语言-一维数组,二维数组

数组 数组的引入如果要在程序中保存一个人的年龄&#xff1f;如何保存&#xff1f; 答&#xff1a;创建一个基于int类型的变量&#xff0c;举例&#xff1a;int age 22如果要在程序中保存一个人的三门课的成绩&#xff1f;如何保存&#xff1f; 答&#xff1a;创建三个基于flo…

如何区别HTML和HTML5?

要区分 HTML&#xff08;通常指 HTML4 及更早版本&#xff09;和 HTML5&#xff0c;主要可以从以下关键方面进行比较&#xff1a;一、文档声明区别 <!-- HTML4 文档声明 --> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http:/…

Java实战:实时聊天应用开发(附GitHub链接)

一、前置技术项目介绍&#xff1a; 项目为局域网沟通软件&#xff0c;类似内网通&#xff0c;核心功能包括昵称输入、聊天界面展示在线人数&#xff08;实时更新&#xff09;、群聊&#xff0c;也可扩展私聊、登录注册、聊天记录存储等功能&#xff0c;结尾附GitHub链接。项目涉…

linux 的list_for_each_entry

linux的宏定义提高了代码的简洁性&#xff0c;但有时候的命名不够完美。比如list_for_each_entry&#xff0c;看名字只知道是遍历list&#xff0c;但一看里面的三个变量参数&#xff0c;有点懵逼。/*** list_for_each_entry - iterate over list of given type* pos: …

分布式面试点

目录 1.分布式理论 为什么CAP不可兼得呢? 2.CAP对应的模型和应用 3.Base理论 4,有哪些分布式锁的案例 5.分布式事务 6.Seata 分布式一致性算法 1. 准备阶段&#xff08;Prepare Phase&#xff09; 2. 接受阶段&#xff08;Accept Phase&#xff09; 3. 学习阶段&…

Neo4j系列---【Linux离线安装neo4j】

Linux离线安装neo4j 1.官方安装文档 地址&#xff1a;https://neo4j.com/docs/operations-manual/current/installation/linux/tarball/ 2.如果浏览器无法访问 修改neo4j.conf,开放所有ip访问 # 允许所有IP地址访问 server.default_listen_address0.0.0.0 3.创建开机自启动服务…

SEO长尾关键词核心实战技巧提升排名

内容概要 本文聚焦于SEO长尾关键词的核心实战技巧&#xff0c;旨在帮助读者精准锁定目标用户的搜索意图&#xff0c;从而提升网站自然排名和获取精准流量。文章将从基础概念入手&#xff0c;系统解析如何挖掘高转化率的长尾关键词&#xff0c;优化内容结构以增强搜索可见度&…

当OT遇见IT:Apache IoTDB如何用“时序空间一体化“技术破解工业物联网数据孤岛困局?

目录 一. 什么是时序数据库&#xff1f; 二. 时序数据库的选型要素 性能指标 架构能力 数据模型与查询能力 安全与权限控制 部署与运维能力 三 Apache IoTDB 简介及安装使用&#xff1a; 安装准备教程 检查 Java 版本 下载与安装 下载 IoTDB 解压文件 配置环境变量 启动…

一文讲透HTML语义化标签

文章目录语义化标签概述HTML标签及其含义常见HTML5语义化标签语义化标签对搜索引擎&#xff08;SEO&#xff09;的影响提升搜索引擎排名增强可访问性改善用户体验语义化标签案例各标签作用说明语义化标签概述 HTML 语义化是指使用恰当的标签来准确表达内容的结构和含义&#x…

Django 实战:静态文件与媒体文件从开发配置到生产部署

文章目录一、静态文件与媒体文件区别与联系配置开发环境配置二、媒体文件实战实战场景定义模型定义序列化器定义视图实战效果三、生产部署说明收集静态文件Nginx配置示例OpenResty配置示例一、静态文件与媒体文件 区别与联系 在 Django 项目中&#xff0c;静态文件&#xff0…

Python自动化分析知网文献:爬取、存储与可视化

1. 引言 在当今的学术研究和大数据分析领域&#xff0c;高效获取和分析学术文献数据具有重要意义。中国知网&#xff08;CNKI&#xff09;作为国内最权威的学术资源平台之一&#xff0c;包含了海量的期刊论文、会议论文和学位论文。然而&#xff0c;手动收集和分析这些数据不仅…