当我将test()调用放入脚本中时,我得到了 NonSerializableException ,当我注释掉 A 行而未注释掉 B 行时,它工作得很好。
与test()在脚本内部和外部进行调用有什么区别?
test()
我现在正在考虑的解决方法是使用when条件Jenkinsfile
when
Jenkinsfile
更新 我怀疑该错误与需要“节点”块的命令有关
#!/usr/bin/env groovy import groovy.json.JsonSlurper @NonCPS def test() { sh "aws ecs update-service --cluster dev-cluster-name --service service-name --desired-count 0 --region us-west-2" } def deployDockerContainer() { script { def describeServices = sh(returnStdout: true, script: "aws ecs describe-services --region us-west-2 --cluster dev-cluster-name --services service-name").trim() def describeServicesJSON = new JsonSlurper().parseText(describeServices) if (describeServicesJSON.services.size() > 0 && describeServicesJSON.services[0].status.equals('ACTIVE')) { test() //A } } // test() //B sh "/usr/local/bin/ecs-cli ps --region us-west-2a --cluster dev-clustername" } pipeline { agent any environment { ENVIRONMENT = 'dev' } parameters { booleanParam(name: 'DEPLOY_TO_DEV', defaultValue: true, description: 'Deploy to Dev Environment?') booleanParam(name: 'DEPLOY_TO_TEST', defaultValue: false, description: 'Deploy to Test Environment?') booleanParam(name: 'DEPLOY_TO_PROD', defaultValue: false, description: 'Deploy to Production Environment?') } stages { stage('DEV:Deploy') { when { expression { return params.DEPLOY_TO_DEV } } environment { ENVIRONMENT = 'dev' } steps { deployDockerContainer() } } } }
堆栈跟踪:
an exception which occurred: in field com.cloudbees.groovy.cps.impl.BlockScopeEnv.locals in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@4c090b96 in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@45444499 in field com.cloudbees.groovy.cps.impl.CallEnv.caller in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@2e3aa6ff in field com.cloudbees.groovy.cps.Continuable.e in object org.jenkinsci.plugins.workflow.cps.SandboxContinuable@8393d12 in field org.jenkinsci.plugins.workflow.cps.CpsThread.program in object org.jenkinsci.plugins.workflow.cps.CpsThread@46045514 in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.threads in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@420ee007 in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@420ee007 Caused: java.io.NotSerializableException: groovy.json.internal.LazyMap at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:860) at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65) at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56) at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50) at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344) at java.util.HashMap.internalWriteEntries(HashMap.java:1790) at java.util.HashMap.writeObject(HashMap.java:1363) at sun.reflect.GeneratedMethodAccessor322.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:273) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854) at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854) at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854) at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854) at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:967) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854) at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854) at org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65) at org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56) at org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50) at org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179) at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:344) at java.util.TreeMap.writeObject(TreeMap.java:2438) at sun.reflect.GeneratedMethodAccessor336.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:273) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854) at org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1032) at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:988) at org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:854) at org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58) at org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:111) at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.lambda$writeObject$0(RiverWriter.java:144) at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:108) at org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:143) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:477) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:453) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgramIfPossible(CpsThreadGroup.java:440) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:367) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$200(CpsThreadGroup.java:83) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:244) at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:232) at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:64) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:131) at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28) at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:59) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at java.lang.Thread.run(Thread.java:748)
aws ecs update-service手动执行:
aws ecs update-service
{ "service": { "serviceArn": "XXXXXXXX", "serviceName": "XXXXXXXX", "clusterArn": "XXXXXXXX", "loadBalancers": [ { "targetGroupArn": "XXXXXXXX", "containerName": "XXXXXXXX", "containerPort": 8080 } ], "serviceRegistries": [], "status": "ACTIVE", "desiredCount": 0, "runningCount": 0, "pendingCount": 0, "launchType": "EC2", "taskDefinition": "XXXXXXXX", "deploymentConfiguration": { "maximumPercent": 200, "minimumHealthyPercent": 100 }, "deployments": [ { "id": "XXXXXXXX", "status": "PRIMARY", "taskDefinition": "XXXXXXXX", "desiredCount": 0, "pendingCount": 0, "runningCount": 0, "createdAt": 1525230109.446, "updatedAt": 1525234874.41, "launchType": "EC2" } ], "roleArn": "XXXXXXXX", "events": [ { "id": "XXXXXXXX", "createdAt": 1525230133.646, "message": "XXXXXXXX has reached a steady state." }, { "id": "XXXXXXXX", "createdAt": 1525230121.278, "message": "XXXXXXXX has stopped 1 running tasks: (task XXXXXXXX)." }, { "id": "XXXXXXXX", "createdAt": 1525230109.914, "message": "(service XXXXXXXX) has started 1 tasks: (task XXXXXXXX)." } ], "createdAt": 1525230109.446, "placementConstraints": [], "placementStrategy": [], "healthCheckGracePeriodSeconds": 0 } }
首先JsonSlurper是不可序列化的。如果要使用它,则必须将其封装到@NonCPS方法中。
JsonSlurper
@NonCPS
其次,您不能在@NonCPS方法中使用任何cps方法,例如sh。
sh
第三,如果您不遵循这些规则,有时管道(cps代码)运行程序不会立即引发错误。有时,对脚本本身进行一些更改后会引发错误。