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 環境中都安全,視具體版本而定。


🔁 最佳實踐推薦

場景推薦方式
生產級流水線中解析 JSON? readJSON
工具方法、輔助轉換? @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
英文地址,請注明出處:http://en.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;手動收集和分析這些數據不僅…