首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法通过jenkins脚本管道中的NotSerializableException

无法通过jenkins脚本管道中的NotSerializableException
EN

Stack Overflow用户
提问于 2020-08-18 13:38:48
回答 1查看 451关注 0票数 0

我有一个管道作业,它运行以下groovy脚本,但是只要jenkins看到带有sh命令的行,就会抛出以下异常。即使用@NonCPS注释了这个方法,我似乎也无法逃脱这个异常的惩罚。我遗漏了什么?

代码语言:javascript
复制
node {
    stage('Kill Long Running jobs') {
        try {
            def longRunningJobs = getLongRunningJobs()
            if (longRunningJobs.size() > 0) {
                def metricData = killAndGetMetricData(longRunningJobs)
                if (metricData.size() > 0) {
                    def payload = metricData.join('\n')
                    sh("curl -X POST ${ENDPOINT} --data-binary ${payload}")
                }
            } else {
                echo 'No long running jobs'
            }
        } catch (err) {
            throw err
        }
    }
}

@NonCPS
def getLongRunningJobs() {
    def timeInMillis = 24*3600*1000
    def rightNow = Calendar.getInstance()
    return Jenkins.instance.getAllItems(Job.class).findAll { Job job ->
        job.isBuilding()
    }.collect { Job job ->
        //find all matching items and return a list but if null then return an empty list
        job.builds.findAll { Run run ->
            run.isBuilding() && ((rightNow.getTimeInMillis() - run.getStartTimeInMillis()) > timeInMillis)
        } ?: []
    }.sum()
}

错误:

代码语言:javascript
复制
an exception which occurred:
    in field com.cloudbees.groovy.cps.impl.BlockScopeEnv.locals
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@5dc513b2
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@788991c6
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@76c7fb80
    in field com.cloudbees.groovy.cps.impl.CallEnv.caller
    in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@41b11dd6
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@4a0dec81
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@21e5f4ba
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.TryBlockEnv@69fbc75f
    in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
    in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@430907d9
    in field com.cloudbees.groovy.cps.impl.CallEnv.caller
    in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@779bb867
    in field com.cloudbees.groovy.cps.Continuable.e
    in object org.jenkinsci.plugins.workflow.cps.SandboxContinuable@e363a3
    in field org.jenkinsci.plugins.workflow.cps.CpsThread.program
    in object org.jenkinsci.plugins.workflow.cps.CpsThread@29a42aee
    in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.threads
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@23c20513
    in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@23c20513
Caused: java.io.NotSerializableException: org.jenkinsci.plugins.workflow.job.WorkflowRun
    at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:926)
EN

回答 1

Stack Overflow用户

发布于 2020-08-18 17:19:48

你真的不应该把像"Job“这样的笨重的内部Jenkins对象泄漏到你管道的CPS部分。由于Jenkins的管道作业类型需要能够在任何时候挂起和恢复管道,所以管道中的所有对象都需要是可序列化的-大多数内部Jenkins对象在设计时都没有考虑到这一点。

如果您确实需要在管道中使用Jenkins内部对象,请将所有这些都包装到@NonCPS方法中。经验法则:在管道CPS代码中只使用像String或List这样的“简单”对象。对于上面的代码,我建议:

  • 要么返回字符串列表(作业名?)从getLongRunningJobs()和modify killAndGetMetricData()获取字符串列表
  • ,或者(可能更简单)重构代码以组合这两种方法,只返回字符串列表(甚至只返回有效负载字符串)

有关更多技术细节,请参阅https://www.jenkins.io/blog/2017/02/01/pipeline-scalability-best-practice/

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63462477

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档