13 Replies Latest reply on Aug 19, 2009 7:45 AM by kukeltje

    Passing objects through the workflow

    mmusaji

      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
          kukeltje

          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
            mmusaji

            Thanks Ronald.

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

            M

            • 3. Re: Passing objects through the workflow
              mmusaji

              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?

              • 4. Re: Passing objects through the workflow
                kukeltje

                show your process....

                • 5. Re: Passing objects through the workflow
                  kukeltje

                  better, show the whole unit test.

                  • 6. Re: Passing objects through the workflow
                    mmusaji

                    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
                      kukeltje

                      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
                        mmusaji

                        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
                          mmusaji

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

                          • 10. Re: Passing objects through the workflow
                            kukeltje

                            no problem

                            • 11. Re: Passing objects through the workflow
                              mmusaji

                              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
                                kukeltje

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

                                • 13. Re: Passing objects through the workflow
                                  kukeltje

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