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

NotSerializableException when create a new instance of GStringTemplateEngine before use readYaml

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Minor Minor

      I am facing a very weird situation on a scripted pipeline which I'm currently playing with.

      In the following code, if I create an instance of GStringTemplateEngine() BEFORE call readYaml step, it breaks. If I create if AFTER, it runs fine.

      Is this supposed to happen?

      Here is the code. To simulate, just paste it to a simple pipeline job,

      import groovy.text.GStringTemplateEngine
      class Context implements Serializable {
          Map<Object, Object> binding
          List<String> untemplated_keys
          String pod_template
          String container_name
          String container_image
          String node
          Script steps
          private Context(Map args) {
              this.binding = args.binding
              this.untemplated_keys = args.untemplated_keys
              this.pod_template = args.pod_template
              this.container_name = args.container_name
              this.container_image = args.container_image
              this.node = args.node
              this.steps = args.steps
          }
          public static Context create(Map args) {
              def untemplated_keys = args.untemplated_keys ?: ['pod_template']
              // Keeping this line here, breaks
              def templateEngine = new GStringTemplateEngine()
              if (args.node == 'k8s' && args.container_image) {
                  def pod_template_map = args.steps.readYaml(text: args.pod_template)
                  def containers = pod_template_map.spec.containers.collect { container ->
                      container.image = args.container_image
                      return container
                  }
                  pod_template_map.spec.containers = containers
                  args.pod_template = args.steps.writeYaml(returnText: true, data: pod_template_map) 
              }  
              // Moving it here, works
              // def templateEngine = new GStringTemplateEngine() 
              args.container_image = updateStringPlaceholders(args.container_image, args.binding, untemplated_keys, templateEngine)
              return new Context(args)
          }
          private static def updateStringPlaceholders(value, Map<Object, Object> binding, List<String> untemplatedKeys, GStringTemplateEngine templateEngine) {
              if (value) {
                  if (value instanceof Map) {
                      value.collectEntries { k, v ->
                          untemplatedKeys.contains(k) ? [k,v] : [k, updateStringPlaceholders(v, binding, untemplatedKeys, templateEngine)] 
                      }
                  } else if (value instanceof List) {
                      value.collect { updateStringPlaceholders(it, binding, untemplatedKeys, templateEngine) }
                  } else {
                      if (value instanceof String) {
                          value.empty ? value : templateEngine.createTemplate(value).make(binding).toString()
                      } else {
                          value
                      }
                  }
              }
          }
      }
      def _package() {
          def pod = """
      apiVersion: v1
      kind: Pod
      spec:
        containers:
        - name: mycontainer
          image: myimage
          imagePullPolicy: Always
          tty: true
          command:
          - cat
      """
          def context = Context.create(
              steps: this, 
              binding: [
                  package_name: "MyPackage", 
                  package_version: "3.0.2", 
              ],
              node: 'k8s',
              container_image: "container-image-<%= package_name %>:<%= package_version %>", 
              container_name: "mycontainer", 
              pod_template: pod,
          )
      }
      _package() 

      This is the error stack:

      [Pipeline] Start of Pipeline
      [Pipeline] readYaml
      [Pipeline] End of Pipeline
      an exception which occurred:
      	in field com.cloudbees.groovy.cps.impl.BlockScopeEnv.locals
      	in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@45bac329
      	in field com.cloudbees.groovy.cps.impl.ProxyEnv.parent
      	in object com.cloudbees.groovy.cps.impl.BlockScopeEnv@7f7a058e
      	in field com.cloudbees.groovy.cps.impl.CallEnv.caller
      	in object com.cloudbees.groovy.cps.impl.FunctionCallEnv@35a1eb7b
      	in field com.cloudbees.groovy.cps.Continuable.e
      	in object org.jenkinsci.plugins.workflow.cps.SandboxContinuable@6654837b
      	in field org.jenkinsci.plugins.workflow.cps.CpsThread.program
      	in object org.jenkinsci.plugins.workflow.cps.CpsThread@47b29298
      	in field org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.threads
      	in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@dcc1436
      	in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@dcc1436
      Also:   org.jenkinsci.plugins.workflow.actions.ErrorAction$ErrorId: a97fb6fa-29f6-485b-99eb-845bd22e7632
      Caused: java.io.NotSerializableException: groovy.text.GStringTemplateEngine
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:278)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
      	at java.base/java.io.ObjectOutputStream.writeObject(Unknown Source)
      	at java.base/java.util.HashMap.internalWriteEntries(Unknown Source)
      	at java.base/java.util.HashMap.writeObject(Unknown Source)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:157)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:231)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1128)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:271)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1182)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1140)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:271)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1182)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1140)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1119)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:271)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1182)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1140)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1119)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:271)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1182)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1140)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1119)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:271)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1182)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1140)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:271)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.BlockMarshaller.doWriteObject(BlockMarshaller.java:65)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.BlockMarshaller.writeObject(BlockMarshaller.java:56)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.MarshallerObjectOutputStream.writeObjectOverride(MarshallerObjectOutputStream.java:50)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverObjectOutputStream.writeObjectOverride(RiverObjectOutputStream.java:179)
      	at java.base/java.io.ObjectOutputStream.writeObject(Unknown Source)
      	at java.base/java.util.HashMap.internalWriteEntries(Unknown Source)
      	at java.base/java.util.HashMap.writeObject(Unknown Source)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.reflect.JDKSpecific$SerMethods.callWriteObject(JDKSpecific.java:157)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:231)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1128)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:271)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteFields(RiverMarshaller.java:1182)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:1140)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.river.RiverMarshaller.doWriteObject(RiverMarshaller.java:271)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.AbstractObjectOutput.writeObject(AbstractObjectOutput.java:58)
      	at PluginClassLoader for workflow-support//org.jboss.marshalling.AbstractMarshaller.writeObject(AbstractMarshaller.java:116)
      	at PluginClassLoader for workflow-support//org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.lambda$writeObject$1(RiverWriter.java:147)
      	at PluginClassLoader for script-security//org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.GroovySandbox.runInSandbox(GroovySandbox.java:331)
      	at PluginClassLoader for workflow-support//org.jenkinsci.plugins.workflow.support.pickles.serialization.RiverWriter.writeObject(RiverWriter.java:146)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:590)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:567)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgramIfPossible(CpsThreadGroup.java:550)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:474)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:331)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:295)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService.lambda$wrap$4(CpsVmExecutorService.java:140)
      	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
      	at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:139)
      	at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
      	at jenkins.security.ImpersonatingExecutorService$1.run(ImpersonatingExecutorService.java:68)
      	at jenkins.util.ErrorLoggingExecutorService.lambda$wrap$0(ErrorLoggingExecutorService.java:51)
      	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
      	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
      	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
      	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$1.call(CpsVmExecutorService.java:53)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$1.call(CpsVmExecutorService.java:50)
      	at org.codehaus.groovy.runtime.GroovyCategorySupport$ThreadCategoryInfo.use(GroovyCategorySupport.java:136)
      	at org.codehaus.groovy.runtime.GroovyCategorySupport.use(GroovyCategorySupport.java:275)
      	at PluginClassLoader for workflow-cps//org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService.lambda$categoryThreadFactory$0(CpsVmExecutorService.java:50)
      	at java.base/java.lang.Thread.run(Unknown Source)
      Finished: FAILURE 

          [JENKINS-75305] NotSerializableException when create a new instance of GStringTemplateEngine before use readYaml

            rsandell rsandell
            galindro Bruno Galindro da Costa
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated: