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

Jenkins流水线调用AWS Lambda时遭遇java.io.NotSerializableException错误求助

Jenkins流水线遍历日期调用AWS Lambda的序列化错误修复

问题场景

通过Jenkins流水线传入起止日期,遍历期间所有日期调用AWS Lambda时,触发以下错误:

Caused: java.io.NotSerializableException: groovy.lang.ObjectRange

原代码

pipeline {
  stages {
    stage('call lambda') {
        steps { 
            call_all(params.START_DATE, params.END_DATE) 
            }
    }
  }
}

def call_all(start_date, end_date) {
    date1 = new Date(start_date)
    date2 = new Date(end_date)
    dates = (date1..date2)
    for(date in dates) { 
      call_by_date("${date.format('yyyy-MM-dd')}") 
    }
}

def call_by_date(job_date) {
    sh "echo calling my_lambda for ${job_date}"
    withAWS(role: "${getAWSRole()}", roleAccount: "${getAWSAccount()}", duration: 1800) {
        sh 'aws lambda invoke \
                    --region "us-XXXX-1" \
                    --function-name "my_lambda" \
                    --invocation-type Event \
                    --payload "{\"date\":\"${job_date}\" }" \
                    /tmp/response.json'
    }
}

def getAWSAccount() {
        return "my_account"
}

def getAWSRole() {
        return "my_role"
}

错误原因

  1. Jenkins流水线执行时会序列化保存全局状态,date1、date2、dates未用def声明,成为全局变量后会被Jenkins尝试序列化
  2. (date1..date2)生成的groovy.lang.ObjectRange对象本身不支持序列化,触发序列化异常
  3. 额外问题:shell命令用单引号包裹时,${job_date}不会被Groovy解析替换,导致Lambda接收的参数错误

修复方案

  1. 用def声明局部变量,避免变量进入全局作用域被序列化
  2. 将ObjectRange转为可序列化的List:(date1..date2).toList()
  3. 改用双引号包裹shell命令,确保Groovy能正确替换变量

修复后代码

pipeline {
  stages {
    stage('call lambda') {
        steps { 
            call_all(params.START_DATE, params.END_DATE) 
        }
    }
  }
}

def call_all(start_date, end_date) {
    def date1 = new Date(start_date)
    def date2 = new Date(end_date)
    def dates = (date1..date2).toList() // 转为可序列化的List
    for(date in dates) { 
      call_by_date("${date.format('yyyy-MM-dd')}") 
    }
}

def call_by_date(job_date) {
    sh "echo calling my_lambda for ${job_date}"
    withAWS(role: "${getAWSRole()}", roleAccount: "${getAWSAccount()}", duration: 1800) {
        // 改用三引号包裹shell命令,确保变量被正确替换
        sh """aws lambda invoke \
                    --region "us-XXXX-1" \
                    --function-name "my_lambda" \
                    --invocation-type Event \
                    --payload "{\"date\":\"${job_date}\" }" \
                    /tmp/response.json"""
    }
}

def getAWSAccount() {
        return "my_account"
}

def getAWSRole() {
        return "my_role"
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 13:07:49