You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Groovy脚本execute的waitFor在Jenkins中挂起,命令行运行正常求助

Jenkins Groovy脚本waitFor()挂起的解决方案

Hey there! I’ve run into this exact issue before—your script works fine in the command line but hangs on waitFor() in Jenkins, right? Let’s break down why this happens and how to fix it.

The Root Cause

When you launch a subprocess with execute() in Groovy, the child process (your svn export command) writes output to stdout and stderr. These streams have limited buffer sizes. If the subprocess generates enough output to fill these buffers, it will stop executing and wait for the parent process (your Jenkins Groovy script) to read the buffered data.

In your current code, you’re calling proc.waitFor() first—this means your script is waiting for the subprocess to finish, but the subprocess is stuck waiting for your script to read its output. That’s a classic deadlock scenario!

Fix 1: Use Groovy’s consumeProcessOutput (Simplest Solution)

Groovy has a built-in method consumeProcessOutput() that spins up background threads to read stdout and stderr as they’re generated. This prevents the buffers from filling up and blocking the subprocess. Here’s how to modify your code:

//checkoutObjects
def command =""
for (i = 0; i < numOfObj; i++) {
    command = "svn export -r ${DeploySetArray[i][1]} ${DeploySetArray[i][0]} D:/Jenkins/workspace/mmb.database.deploy"
    def proc = command.execute()
    
    // Capture output and error in buffers using background threads
    def stdoutBuffer = new StringBuilder()
    def stderrBuffer = new StringBuilder()
    proc.consumeProcessOutput(stdoutBuffer, stderrBuffer)
    
    // Now wait for the process to finish safely
    proc.waitFor()
    
    println "Process exit code: ${proc.exitValue()}"
    println "Std Err: ${stderrBuffer.toString()}"
    println "Std Out: ${stdoutBuffer.toString()}"
}

Fix 2: Manual Threaded Output Reading

If you prefer more control over how output is handled, you can start separate threads to read stdout and stderr before calling waitFor():

//checkoutObjects
def command =""
for (i = 0; i < numOfObj; i++) {
    command = "svn export -r ${DeploySetArray[i][1]} ${DeploySetArray[i][0]} D:/Jenkins/workspace/mmb.database.deploy"
    def proc = command.execute()
    
    // Start threads to read output immediately
    def stdoutThread = Thread.start {
        proc.in.eachLine { line ->
            println "Std Out: $line"
        }
    }
    def stderrThread = Thread.start {
        proc.err.eachLine { line ->
            println "Std Err: $line"
        }
    }
    
    // Wait for the process and threads to finish
    proc.waitFor()
    stdoutThread.join()
    stderrThread.join()
    
    println "Process exit code: ${proc.exitValue()}"
}

Bonus: Use Jenkins Native SVN Steps (Most Reliable)

Instead of rolling your own svn export command in Groovy, consider using Jenkins’ built-in SVN plugin steps. These are designed to handle output buffering and integrate better with Jenkins’ logging and job status. Here’s an example:

for (i = 0; i < numOfObj; i++) {
    def svnUrl = DeploySetArray[i][0]
    def revision = DeploySetArray[i][1]
    def targetDir = "D:/Jenkins/workspace/mmb.database.deploy"
    
    svn(
        url: svnUrl,
        revision: revision,
        checkoutDir: targetDir,
        additionalArgs: "--export" // Use export instead of checkout
    )
}

Just make sure you have the Jenkins SVN plugin installed and configured properly for your environment.

内容的提问来源于stack exchange,提问作者Matt Kimball

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:47:34