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

Pipeline implementing readObject/writeObject fails with ProxyException CpsCallableInvocation

XMLWordPrintable

    • Icon: Improvement Improvement
    • Resolution: Unresolved
    • Icon: Minor Minor
    • workflow-cps-plugin

      I have a set of steps which share a configuration instance. The configuration is implemented as Singleton. Now, I would like to serialize this @Singleton to support the resume feature of Jenkins pipelines. Currently, all runtime configurations are gone, if the Jenkins is restarted in between.

      Since statics aren't serialized, I implemented readObject and writeObject. What ever I tried, i came across the ProxyException: 

      hudson.remoting.ProxyException: CpsCallableInvocation{methodName=writeObject, call=com.cloudbees.groovy.cps.impl.CpsFunction@1bc872bf, receiver=my.simple.TestPipelineEnvironment@40f84a32, arguments=[org.jboss.marshalling.river.RiverObjectOutputStream@8ad5752]}
      

      In the code below, I implemented the simple POGO my.simple.TestPipelineEnvironment.groovy with readObject and writeObject. I dropped the @Singleton to reduce complexity.

      package my.simple;
      
      public class TestPipelineEnvironment implements Serializable {
      
      	private void writeObject(ObjectOutputStream oos) throws IOException {
      		System.out.println("Custom serialization logic invoked.");
      		oos.defaultWriteObject();
      	}
      	private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
      		System.out.println("Custom deserialization logic invoked.");
      		ois.defaultReadObject();
      	}
      
      	private Map valueMap = [:]
      
      	void setValue(String property, value) {
      		valueMap[property] = value
      	}
      
      	def getValue(String property) {
      		return valueMap.get(property)
      	}
      }
      
      
      

      It is initialized and accessible by the step vars/testPipelineEnvironment.groovy

       

      import my.simple.TestPipelineEnvironment
      
      class testPipelineEnvironment implements Serializable {
      
          private static final long serialVersionUID = -113665469917946598L;
      
          private TestPipelineEnvironment instance= new TestPipelineEnvironment();
      
          private TestPipelineEnvironment getCPE() {
              return instance;
          }
      
          Map getValueMap() {
              getCPE().valueMap
          }
      
          void setValue(String property, value) {
              valueMap[property] = value
          }
      
          def getValue(String property) {
              return valueMap.get(property)
          }
      }

      The Jenkinsfile fails

       

      @Library('piper-lib-rodibrin') _
      node() {
        stage('prepare') { 
          testPipelineEnvironment.setValue("key","value") echo "value:" + testPipelineEnvironment.getValue("key") 
        }
      }
      

      with

       

      ...
      [Pipeline] echo
       value:value
       [Pipeline] }
       [Pipeline] End of Pipeline
       hudson.remoting.ProxyException: CpsCallableInvocation{methodName=writeObject, call=com.cloudbees.groovy.cps.impl.CpsFunction@1bc872bf, receiver=my.simple.TestPipelineEnvironment@40f84a32, arguments=[org.jboss.marshalling.river.RiverObjectOutputStream@8ad5752]}
       Finished: FAILURE
      

       

            Unassigned Unassigned
            rodibrin Roland Stengel
            Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated: