Jenkins部署流水线启动jar后Karate测试阶段无法执行问题
问题原因
流水线卡在run jar file阶段无法推进的核心原因:你通过bat步骤执行java -jar命令时,Java服务会以前台进程模式运行,只要服务进程不退出,当前批处理命令就不会返回执行结束的状态,Jenkins会一直阻塞等待该步骤完成,自然无法触发后续的Karate测试阶段。
修复方案
1. 修改服务启动方式为后台运行
Windows环境下可以使用start /b命令将Java服务放到后台运行,启动命令执行完会立刻返回,不会阻塞流水线,同时把服务运行日志重定向到文件方便排查问题。
stage('run jar file'){ dir("target") { // 后台启动jar包,日志输出到当前目录的app.log bat "start /b java -jar erms-1.0-SNAPSHOT-jar-with-dependencies.jar > app.log 2>&1" } }
2. 增加服务就绪校验(必加,避免测试提前执行)
不建议靠固定等待时长判断服务状态,推荐用端口探测逻辑,确认服务端口正常监听后再进入测试阶段,以下是探测8080端口(替换为你实际服务使用的端口)的示例:
stage('run jar file'){ dir("target") { bat "start /b java -jar erms-1.0-SNAPSHOT-jar-with-dependencies.jar > app.log 2>&1" // 最多等待60秒,每2秒探测一次服务端口 powershell ''' $maxRetry = 30 $count = 0 while ($count -lt $maxRetry) { $portTest = Test-NetConnection -ComputerName 127.0.0.1 -Port 8080 -WarningAction SilentlyContinue if ($portTest.TcpTestSucceeded) { Write-Host "Service is ready" exit 0 } Start-Sleep -Seconds 2 $count++ } Write-Error "Service failed to start in 60 seconds, check app.log for details" exit 1 ''' } }
3. 增加进程清理逻辑
在流水线最后增加后置步骤,构建结束(无论成功失败)时自动杀掉启动的Java进程,避免残留进程占用端口导致下次构建失败:
post { always { // 杀掉对应jar包启动的java进程 bat "wmic process where \"commandline like '%%erms-1.0-SNAPSHOT-jar-with-dependencies.jar%%'\" call terminate > nul 2>&1" } }
修改后完整流水线参考
node { def mavenHome = tool name: "Maven", type: "maven" stage('git clone') { checkout([$class: 'GitSCM', branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[credentialsId: 'b6423164-b18d-43e0-a48f-edd10f90396d', url: 'https://github.com/prajdshakya93/Employee-Record-Managment-System.git']]]) } stage('build artifact with dependencies'){ bat "${mavenHome}/bin/mvn clean compile assembly:single" bat("xcopy config.properties C:\\ProgramData\\Jenkins\\.jenkins\\workspace\\ermsPipelinePratice\\target") } stage('run jar file'){ dir("target") { bat "start /b java -jar erms-1.0-SNAPSHOT-jar-with-dependencies.jar > app.log 2>&1" powershell ''' $maxRetry = 30 $count = 0 while ($count -lt $maxRetry) { $portTest = Test-NetConnection -ComputerName 127.0.0.1 -Port 8080 -WarningAction SilentlyContinue if ($portTest.TcpTestSucceeded) { Write-Host "Service is ready" exit 0 } Start-Sleep -Seconds 2 $count++ } Write-Error "Service failed to start in 60 seconds, check app.log for details" exit 1 ''' } } stage('run karate'){ bat "${mavenHome}/bin/mvn test -Dtest=KarateTests" } post { always { bat "wmic process where \"commandline like '%%erms-1.0-SNAPSHOT-jar-with-dependencies.jar%%'\" call terminate > nul 2>&1" } } }
补充:如果你的Jenkins节点跑在Linux系统上,逻辑完全一致,只需要把
bat替换为sh,后台启动命令改为nohup java -jar erms-1.0-SNAPSHOT-jar-with-dependencies.jar > app.log 2>&1 &,端口探测和进程杀掉的命令换成对应Linux命令即可。
内容的提问来源于stack exchange,提问作者Prajwal Shakya
相关产品推荐
相关产品推荐

