13 Replies Latest reply on Aug 19, 2009 7:45 AM by Ronald van Kuijk

    Passing objects through the workflow

    Mustafa Musaji Novice

      Hi,

      I have an object which I need to pass through the workflow. The object implements Serializable and I can succesfully read the object from any class which implements ActivityBehaviour.

      I am struggling to understand how I go about re-serializing the object so the next call to a class implement ActivityBehaviour can read the serialized object with the changes the previous class made to it?

      I just need someone to point me in the right direction as I'm sure I'm missing something fairly straight forward with my set up.

      Thanks.
      M

        • 1. Re: Passing objects through the workflow
          Ronald van Kuijk Master

          Process variables should exactly behave like this. So please give that a try or make a unit test that demonstrates what you want to do.

          • 2. Re: Passing objects through the workflow
            Mustafa Musaji Novice

            Thanks Ronald.

            I'll look in to this and I will give that a try.

            M

            • 3. Re: Passing objects through the workflow
              Mustafa Musaji Novice

              I am creating a variable and starting the process by providing these variables on startup.

              MyObject myObject = new MyObject();
              myObject.setName("a name to set");
              
              variables.put("myObj", myObject);
              
              ProcessInstance processInstance = executionService.startProcessInstanceByKey("process", variables);
              


              The workflow calls the class which implements the ActivityBehaviour interface.

              <custom name="validate" class="org.tlg.workflow.AlterObject" exp="#{anObj}">
               <transition g="-27,-18" name="" to="end"/>
               </custom>
              


              Now unfortunately this is where I become stuck. In AlterObject class I cast the object back and amend details.

              MyObject myObject= (MyObject )execution.getVariable("anObj");
              myObject.setName("A different name"); //name should change
              execution.setVariable("myObj", myObject);
              


              Going back to my Junit I want to ensure them changes have taken effect. If I use the processInstanceId that kicked off the workflow the process has ended already, and if I use the existing hashmap to get the variable I have just set, I get the old value set in the object.

              Is my workflow implementation correct for what I am trying to do?

              • 5. Re: Passing objects through the workflow
                Ronald van Kuijk Master

                better, show the whole unit test.

                • 6. Re: Passing objects through the workflow
                  Mustafa Musaji Novice

                  Okay so here's my workflow

                  <?xml version="1.0" encoding="UTF-8"?>
                  
                  <process name="process" xmlns="http://jbpm.org/4.0/jpdl">
                   <start g="0,0,80,40">
                   <transition to="parse request"/>
                   </start>
                  
                   <java class="org.tlg.workflow.ParseRequest" g="90,4,80,40" method="execute" name="parse request">
                   <transition g="-27,-18" name="valid" to="find providers"/>
                   <transition g="-35,-18" name="invalid" to="error"/>
                   </java>
                  
                   <java class="org.tlg.workflow.FindProviders" g="276,7,80,40" method="execute" name="find providers">
                   <transition to="fork"/>
                   </java>
                  
                   <fork g="298,85,80,40" name="fork">
                   <on continue="exclusive" event="end"/>
                   <transition g="-62,-18" name="validate red" to="validate red request"/>
                   <transition g="-64,-18" name="validate exp" to="validate exp request"/>
                   <transition g="-63,-17" name="validate sys" to="validate sys request"/>
                   </fork>
                  
                   <custom name="validate red request" class="org.tlg.workflow.AlterObject" exp="#{myObj}">
                   <transition g="-27,-18" to="join"/>
                   </custom>
                  
                   <custom name="validate exp request" class="org.tlg.workflow.AlterObject" exp="#{myObj}">
                   <transition g="-27,-18" to="join"/>
                   </custom>
                  
                   <custom name="validate sys request" class="org.tlg.workflow.AlterObject" exp="#{myObj}">
                   <transition g="-27,-18" to="join"/>
                   </custom>
                  
                   <join g="267,368,80,40" name="join">
                   <transition name="check results" to="evaluate validation results" g="-47,-16"/>
                   </join>
                  
                   <decision name="evaluate validation results" expr="#{content}" >
                   <transition name="valid" to="construct message" />
                   <transition name="invalid" to="error"/>
                   </decision>
                  
                   <java class="org.tlg.workflow.ConstructFraudRequest" g="505,168,80,40" method="execute" name="construct message">
                   <transition to="send"/>
                   </java>
                  
                   <java class="org.tlg.workflow.SendRequest" g="501,78,80,40" method="execute" name="send">
                   <transition to="get responses"/>
                   </java>
                  
                   <java class="org.tlg.workflow.GetResponse" g="372,84,80,40" method="execute" name="get responses">
                   <transition to="process responses"/>
                   </java>
                  
                   <java class="org.tlg.workflow.ProcessResponse" g="431,6,80,40" method="execute" name="process responses">
                   <transition g="-48,-18" name="complete" to="end"/>
                   <transition g="-42,-18" name="process" to="find providers"/>
                   </java>
                  
                   <end g="624,21,80,40" name="end" state="complete"/>
                   <end-error g="37,104,80,40" name="error"/>
                  
                   </process>
                  


                  It is experimental at the moment so i know it may be a bit messy and i apologize.

                  Here's my Unit test
                  public void testSimple() throws Exception {
                   Map<String, Object> variables = new HashMap<String, Object>();
                   variables.put("content", "valid");
                  
                   myObj = new MyObject();
                   myObj.setName("A reusable fraud object");
                   variables.put("myObj", myObj);
                  
                   ProcessInstance processInstance = executionService.startProcessInstanceByKey("process", variables);
                   String processInstanceId = processInstance.getId();
                  
                   List<Job> jobs = managementService.createJobQuery()
                   .processInstanceId(processInstanceId)
                   .list();
                  
                   for(Job job: jobs) {
                   managementService.executeJob(job.getId());
                   System.out.println("Executing Job number " + job.getId());
                   }
                  
                   MyObject myObjUpdated = (MyObject) variables.get("myObj");
                   System.out.println(myObjUpdated.getName());
                   }
                  


                  And the class that amends the object
                  
                  public class AlterObject implements ActivityBehaviour{
                  
                   private static final long serialVersionUID = 1L;
                  
                   public void execute(ActivityExecution execution) throws Exception {
                   MyObject myObject= (MyObject )execution.getVariable("myObj");
                  
                   System.out.println(myObject.getName());
                   fraudObject.setName("Name now changed");
                  
                   execution.setVariable("myObj", myObject);
                  
                  }
                  
                  



                  • 7. Re: Passing objects through the workflow
                    Ronald van Kuijk Master

                    Yep, was afraid of this.

                    You odo not have any states in your definition, once it passes through all nodes, it is ended and removed from the active database to the history database. Good in one way, troublesome in this case.

                    Just add a task before the end nodes and you can see the variables (querying the history table for variables does not work fully afaik, but you could give that a try as well)

                    • 8. Re: Passing objects through the workflow
                      Mustafa Musaji Novice

                      Hi Roland

                      Thank you very much. It works like a charm now.

                      Be sure I will be back with some more newbie questions but just wanted to say thank you very much for your time and explanation on why it doesn't work.

                      Regards
                      M

                      • 9. Re: Passing objects through the workflow
                        Mustafa Musaji Novice

                        Don't know why I'm calling you Roland :) Sorry, I meant Ronald!

                        • 11. Re: Passing objects through the workflow
                          Mustafa Musaji Novice

                          As I am new to jBPM I was wondering from my workflow if there was anything you could suggest that would improve it?

                          I have no wait states and thus all the java nodes will probably end up being custom nodes passing an object from one to the other till the end. Is this ok?



                          • 12. Re: Passing objects through the workflow
                            Ronald van Kuijk Master

                            If it does the job, scales well, I would change nothing

                            • 13. Re: Passing objects through the workflow
                              Ronald van Kuijk Master

                              or is it 'I wouldn't change anything'?