15574

NonSerializableException inside script block

Question:

I get a <em>NonSerializableException</em> when i put my test() call inside a script, when I commented out line <strong>A</strong> and uncommented out line <strong>B</strong>, it works just fine.

What's the difference from calling test() inside a script and outside of it?

The workaround I'm considering for now is to use the when conditions for Jenkinsfile

<strong>UPDATE</strong> I suspect that the error is related to <a href="https://medium.com/garbage-collection/jenkins-pipelines-what-i-wish-i-knew-starting-out-6e3d4eb2ff5b" rel="nofollow">Commands Requiring a “node” Block</a>

Jenkinsfile

<pre class="lang-groovy prettyprint-override">#!/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() } } } }

Stacktrace:

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)

Executing aws ecs update-service manually:

<pre class="lang-json prettyprint-override">{ "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 } }

Answer1:

First of all JsonSlurperis not serializable. If you want to use it you have to encapsulate it into a @NonCPS method.

Second you cannot use any cps methods from within a @NonCPS method, like sh.

Third, sometimes the pipeline (cps code) runner does not immediately throw an error if you do not follow those rules. Sometimes the error is thrown after doing some changes to the script which itself are correct.

Recommend

  • Replace Multiple If\\Else with Design Pattern
  • soft keyboard is covering bottom sheet dialog
  • How can i solve the warning about TcpListener: Please use TcpListener(IPAddress localaddr, int port)
  • Spring request mapping to a different method for a particular path variable value
  • Select * sql query vs Select specific columns sql query [duplicate]
  • How to add CORS (cross origin policy) to all domains in NGINX?
  • Fetching CloudWatch metrics using the AWS Java SDK?
  • getWidth Returns 0 in Fragment, getPaddingLeft Returns Non-Zero
  • In a database, how to store event occurrence dates and timeframes for fast/elegant querying?
  • How to get OEM USB driver for Samsung Galaxy SIII with model number GT-I9300
  • Adding multiple rows to DataTable
  • Documenting Macro Functions in C++ with Doxygen
  • Convert microseconds string to date in Java or Scala
  • Make a timer reset every 30 days?
  • Getting result.getDriveFolder().getDriveId().getResourceId() always null
  • Programmatic hibernate configuration after xml configuration
  • Azure Container Group IP Address disappeared
  • Model binding not working with Stream type parameter in asp.net core webapi controller action method
  • Activate UISearchBar when the controller is loaded
  • Select running balance from table credit debit columns
  • ExtJS: How to use itemSelector for XTemplate having nested loop?
  • GitLab runner on Windows and dealing with & %ERRORLEVEL%
  • How to share functions between components in angular?
  • Saving CLLocation error: Mutating method sent to immutable object
  • Nested AJAX Calls using .done
  • Error processing job: Project has not enabled BigQuery
  • Php artisan optimize is failing on production server
  • Auto send email based on the time and email address in database
  • Defer unused CSS
  • Add checkbox dynamically using angular 2
  • Ajax call on Multiple selection in Select box
  • Creating 2d platforms using JavaScript
  • Typeahead.js does give me suggestions but doesn't select them
  • How to include associated objects using gon in Rails/jQuery
  • How to get rgb from transparent pixel in js
  • Why my AngularJS async test in Jasmine 1.3.x is not working?
  • Capture SIGFPE from SIMD instruction
  • How to use FirstOrDefault inside Include
  • WPF custom control and direct content support
  • Write to .csv file with PHP (Commas in Data Error)