title: "java.io.NotSerializableException: java.io.PrintWriter" when writing file - jenkins workflow
body: <p>We have a piece of workflow code that does these things:</p>
  
  <p>1 Loads some files from disk</p>
  
  <p>2.Renders their contents using a SimpleTemplateEngine and bindings</p>
  
  <p>3.Writes their result to another files.</p>
  
  <pre><code>def renderTemplates(binding) {
    //stage "Render templates"
    sh "find $infraDir/*.tpl -printf '%f\n' &gt; result"
    def files = readFile('result').split('\n')
    println("Found tpl files -&gt; $files")
    sh "rm result"  //Remove the result file
  
    for(int i=0; i&lt;files.size(); i++){
      def tpl = files[i]
      println("Process tpl file ${tpl}")
      renderTemplate(readFile("${infraDir}/${tpl}"), tpl, binding)
    }
  }
  
  @NonCPS
  def renderTemplate(String input,String tpl, binding){
    def template = new groovy.text.SimpleTemplateEngine().createTemplate(input).make(binding)
    def rendered = template.toString()
    def newFileName = "$infraDir/${tpl.replaceFirst(/\.tpl$/, "")}"
    //sh "echo ${rendered} &gt; ${newFileName}" //--&gt; GIVES ERROR
    writeFile file: newFileName, text: rendered // --&gt; ERROR AS WELL
  }
  </code></pre>
  
  <p>However, the workflow fails everytime with this error:</p>
  
  <pre><code>java.io.NotSerializableException: java.io.PrintWriter
  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.LinkedHashMap.internalWriteEntries(LinkedHashMap.java:333)
  at java.util.HashMap.writeObject(HashMap.java:1354)
  at sun.reflect.GeneratedMethodAccessor97.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:497)
  at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
  at org.jboss.marshalling.river.RiverMarshaller.doWriteSerializableObject(RiverMarshaller.java:976)
  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.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:1777)
  at java.util.HashMap.writeObject(HashMap.java:1354)
  at sun.reflect.GeneratedMethodAccessor97.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:497)
  at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
  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.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.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:2434)
  at sun.reflect.GeneratedMethodAccessor394.invoke(Unknown Source)
  at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
  at java.lang.reflect.Method.invoke(Method.java:497)
  at org.jboss.marshalling.reflect.SerializableClass.callWriteObject(SerializableClass.java:271)
  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.writeObject(RiverWriter.java:132)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:371)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.saveProgram(CpsThreadGroup.java:355)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.run(CpsThreadGroup.java:309)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup.access$000(CpsThreadGroup.java:77)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:186)
  at org.jenkinsci.plugins.workflow.cps.CpsThreadGroup$2.call(CpsThreadGroup.java:184)
  at org.jenkinsci.plugins.workflow.cps.CpsVmExecutorService$2.call(CpsVmExecutorService.java:47)
  at java.util.concurrent.FutureTask.run(FutureTask.java:266)
  at hudson.remoting.SingleLaneExecutorService$1.run(SingleLaneExecutorService.java:112)
  at jenkins.util.ContextResettingExecutorService$1.run(ContextResettingExecutorService.java:28)
  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:1142)
  at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
  at java.lang.Thread.run(Thread.java:745)
  Caused by: an exception which occurred:
  in field locals
  in field parent
  in field parent
  in field parent
  in field caller
  in field e
  in field program
  in field threads
  in object org.jenkinsci.plugins.workflow.cps.CpsThreadGroup@5fc05e47
  Finished: FAILURE
  </code></pre>
  
  <p>I tried using sh to echo to a file, but that fails too.
  Tried removing @NonCPS, that too an error.</p>
  
  <p>If I comment out the writeFile and sh lines, the workflow succeeds, but obviously the file is not written.</p>
  
  <p>Not sure what I am doing wrong.</p>
  
  <p>Any advice?</p>