[JIRA] (JENKINS-61169) Non-Serializable exception thrown on wrong object

8 views
Skip to first unread message

matthew.eggers@nike.com (JIRA)

unread,
Feb 20, 2020, 12:43:02 PM2/20/20
to jenkinsc...@googlegroups.com
Matthew Eggers created an issue
 
Jenkins / Bug JENKINS-61169
Non-Serializable exception thrown on wrong object
Issue Type: Bug Bug
Assignee: Suresh Kumar
Components: core, file-operations-plugin, pipeline-utility-steps-plugin
Created: 2020-02-20 17:42
Environment: Jenkins 2.164.1
pipelines-groovy plugin
Priority: Major Major
Reporter: Matthew Eggers

I am getting an exception when attempting to serialize a groovy Map that I've generated:

an exception which occurred:
	in field groovy.lang.Closure.delegate
	in object Script1$_run_closure1@30d6aac5
	in field com.nike.acid.pipeline.configuration.adaptors.AdvancedClientAdaptor.clientConverter
	in object com.nike.acid.pipeline.configuration.adaptors.AdvancedClientAdaptor@629f71ba
	in field com.cloudbees.groovy.cps.impl.BlockScopeEnv.locals
	in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@2c17fa09
	in field com.cloudbees.groovy.cps.impl.CallEnv.caller
	in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@1635b321
	in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
	in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@146f27c2
	in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
	in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@19d1436
	in field com.cloudbees.groovy.cps.impl.CallEnv.caller
	in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@1d8bbdc9
	in field com.cloudbees.groovy.cps.Continuable.e
	in object org.jenkinsci.plugins.workflow.cps.SandboxContinuable@39c61bdb
	in field org.jenkinsci.plugins.workflow.cps.CpsThread.program
	in object org.jenkinsci.plugins.workflow.cps.CpsThread@7ebbe670
	in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.threads
	in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@3b2aa9f8
	in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@3b2aa9f8
Caused: java.io.NotSerializableException: Script1 

The problem here is, I'm not asking AdvancedClientAdaptor to persist the clientConverter field (It has Closures in it). I'm asking it to persist a JsonStringified groovy map.

 

The issue appears to be in the AdvanceClientAdaptor class I've written. It accepts groovy map that it performs transformations on. Here is a trivial example:

 

def Map = [
   targetConfig: [
      foo: "bar"
   ],
   clientConverter: [
      foo: { targetConfig, value -> targetConfig['foo'] = value
   }]
] 

 The AdvancedClientConverter class basically accepts this Map as an input, assigns 2 member property variables to each of the 2 map fields above:

class AdvancedClientConverter implements Serializable {
   Map targetConfig
   Map clientConverter
   def steps //running groovy instance

   AdvancedClientConverter(Map converterMap, def steps) {
      this.clientConverter = converterMap.clientConverter
      this.targetConfig = converterMap.targetConfig
   }

   def converterOperation() {
      this.targetConfig.foo = this.clientConverter.foo(this.targetConfig, "baz");
      String fileString = JsonOutput.prettyPrint(JsonOutput.toJson(targetConfig))}
      steps.echo ("final config: ${fileString}")
      steps.writeFile file: "FinalConfig.text", text: fileString
      return target
   }
} 

The above is all invoked in a running Jenkins Pipeline:

#!groovy
@Library(['pipeline-library-with-advanced-client-adaptor']) _

def config = []
def converterMap = //converter map listed above
node {
    def advancedClientAdaptor = new AdvancedClientAdaptor(this, converterMap)
    //Failure:
    advancedClientAdaptor.converterOperation()
}

This will throw the above exception. The actual object persisted however, looks accurate. The echo step prior to the writeFile call produces:

{
   "foo": "baz"
}

Yet the exception is thrown on a Completely different field that I am not persisting

Even though, those values entered this class as part of the same map, they are assigned as separate member variables and presumably, different memory addresses.

The String being persisted appears sanitary (No closures or other Non-serializable entities)

This does not occur in JVM (Java 11) running Groovy 1.5.8 performing File.write commands.

The writeFile operation succeeds if using the @NonCPS annotation (but @NonCPS breaks other functionality of the class)

Please let me know if you need additional details or a working sample app that reproduces this issue.

Add Comment Add Comment
 
This message was sent by Atlassian Jira (v7.13.6#713006-sha1:cc4451f)
Atlassian logo

matthew.eggers@nike.com (JIRA)

unread,
Feb 20, 2020, 12:46:03 PM2/20/20
to jenkinsc...@googlegroups.com
Matthew Eggers updated an issue
Change By: Matthew Eggers
I am getting an exception when attempting to serialize a groovy Map that I've generated:
{code:java}

an exception which occurred:
in field groovy.lang.Closure.delegate
in object Script1$_run_closure1@30d6aac5
in field com.nike.acid.pipeline.configuration.adaptors.AdvancedClientAdaptor.clientConverter
in object com.nike.acid.pipeline.configuration.adaptors.AdvancedClientAdaptor@629f71ba
in field com.cloudbees.groovy.cps.impl.BlockScopeEnv.locals
in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@2c17fa09
in field com.cloudbees.groovy.cps.impl.CallEnv.caller
in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@1635b321
in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@146f27c2
in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@19d1436
in field com.cloudbees.groovy.cps.impl.CallEnv.caller
in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@1d8bbdc9
in field com.cloudbees.groovy.cps.Continuable.e
in object org.jenkinsci.plugins.workflow.cps.SandboxContinuable@39c61bdb
in field org.jenkinsci.plugins.workflow.cps.CpsThread.program
in object org.jenkinsci.plugins.workflow.cps.CpsThread@7ebbe670
in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.threads
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@3b2aa9f8
in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@3b2aa9f8
Caused: java.io.NotSerializableException: Script1 {code}

The problem here is, I'm not asking {{AdvancedClientAdaptor}} to persist the {{clientConverter}} field (It has Closures in it). I'm asking it to persist a JsonStringified groovy map.

 

The issue appears to be in the {{AdvanceClientAdaptor}} class I've written. It accepts groovy map that it performs transformations on. Here is a trivial example:

 
{code:java}

def Map = [
   targetConfig: [
      foo: "bar"
   ],
   clientConverter: [
      foo: { targetConfig, value -> targetConfig['foo'] = value
   }]
] {code}
 The {{AdvancedClientConverter}} class basically accepts this Map as an input, assigns 2 member property variables to _each_ of the 2 map fields above:
{code:java}

class AdvancedClientConverter implements Serializable {
   Map targetConfig
   Map clientConverter
   def steps //running groovy instance

   AdvancedClientConverter(Map converterMap, def steps) {
      this.clientConverter = converterMap.clientConverter
      this.targetConfig = converterMap.targetConfig
      this.steps = steps
   }

   def converterOperation() {
      this.targetConfig.foo = this.clientConverter.foo(this.targetConfig, "baz");
      String fileString = JsonOutput.prettyPrint(JsonOutput.toJson(targetConfig))}
      steps.echo ("final config: ${fileString}")
      steps.writeFile file: "FinalConfig.text", text: fileString
      return target
   }
} {code}


The above is all invoked in a running Jenkins Pipeline:
{code}

#!groovy
@Library(['pipeline-library-with-advanced-client-adaptor']) _

def config = []
def converterMap = //converter map listed above
node {
    def advancedClientAdaptor = new AdvancedClientAdaptor(this, converterMap)
    //Failure:
    advancedClientAdaptor.converterOperation()
}
{code}

This will throw the above exception. The actual object persisted however, looks accurate. The echo step prior to the {{writeFile}} call produces:

{code}
{
   "foo": "baz"
}
{code}

Yet the exception is thrown on a _Completely different field that I am not persisting_

Even though, those values entered this class as part of the same map, they are _assigned as separate member variables_ and presumably, different memory addresses.

The String being persisted appears sanitary (No closures or other Non-serializable entities)

This does not occur in JVM (Java 11) running Groovy 1.5.8 performing File.write commands.

The {{writeFile}} operation succeeds if using the @NonCPS annotation (but @NonCPS breaks other functionality of the class)

Please let me know if you need additional details or a working sample app that reproduces this issue.

matthew.eggers@nike.com (JIRA)

unread,
Feb 20, 2020, 12:48:03 PM2/20/20
to jenkinsc...@googlegroups.com
This does not occur in JVM (Java 11) running Groovy 1 2 .5.8 performing File.write commands.


The {{writeFile}} operation succeeds if using the @NonCPS annotation (but @NonCPS breaks other functionality of the class)

Please let me know if you need additional details or a working sample app that reproduces this issue.

matthew.eggers@nike.com (JIRA)

unread,
Feb 21, 2020, 1:52:05 PM2/21/20
to jenkinsc...@googlegroups.com
pipeline.configuration.adaptors.AdvancedClientAdaptor@629f71ba
This does not occur in JVM (Java 11) running Groovy 2.5.8 performing File.write commands.


The {{writeFile}} operation succeeds if using the @NonCPS annotation (but @NonCPS breaks other functionality of the class)

Please let me know if you need additional details or a working sample app that reproduces this issue.

dbeck@cloudbees.com (JIRA)

unread,
Feb 24, 2020, 6:59:03 PM2/24/20
to jenkinsc...@googlegroups.com
Daniel Beck updated an issue
Change By: Daniel Beck
Component/s: workflow-cps-plugin
Component/s: core
Reply all
Reply to author
Forward
0 new messages