Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-61169

Non-Serializable exception thrown on wrong object

      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.pipeline.configuration.adaptors.AdvancedClientAdaptor.clientConverter
      	in object com.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
            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
         }
      } 

      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 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.

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

          Matthew Eggers created issue -
          Matthew Eggers made changes -
          Description Original: 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
             }

             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.
          New: 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 made changes -
          Description Original: 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.
          New: 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 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 made changes -
          Description Original: 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 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.
          New: 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.pipeline.configuration.adaptors.AdvancedClientAdaptor.clientConverter
          in object com.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 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.
          Daniel Beck made changes -
          Component/s New: workflow-cps-plugin [ 21713 ]
          Component/s Original: core [ 15593 ]

            pskumar448 Suresh Kumar
            eggmatters Matthew Eggers
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: