9 Replies Latest reply on May 15, 2009 4:51 PM by Jarkko Lietolahti

    How to define a process definition that has multiples sub-pr

    Pedro Alfaro Newbie

      Use Case
      - create a process definition that manage new files in the system.
      - Read a file that has multiples records.
      - create a sub-process to manage each record.
      - after all sub-process are created wait until all sub-processes finish.
      - report that the file was processed.

      I implemented this use case using an action that create the sub-process, but the problem with it is that the parent process don't wait until all processes finish.
      Could you give me an idea how to implement this?
      Thanks
      Next is my process definition and my action code.

      process definition
      **********************
      <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="listingloads">
      <start-state name="load new file">
      <transition to="join1">
      <action name="action" class="com.sample.action.listingloads.FileDropsActionHandler">
      </action>
      </transition>
      </start-state>
      <join name="join1">
      <transition to="end"></transition>
      </join>
      <end-state name="end"></end-state>
      </process-definition>
      
      Action(I use this code to create the sub-processes)
      ***************************************************************
      ProcessInstance pi = context.getJbpmContext().newProcessInstance( "process-a-record" );
      context.setSubProcessInstance( pi );
      pi.getContextInstance().setVariable( "message", message );
      pi.getContextInstance().setVariable( "fileName", fileName );



        • 1. Re: How to define a process definition that has multiples su
          Ronald van Kuijk Master

          use a custom fork handler. Look in the wiki for an example. Instead of a task node that is created multiple times, put a sub process in between

          • 2. Re: How to define a process definition that has multiples su
            asaf sh Expert

            Where is that example?
            I would like to take a look at it as well,



            Thanks.

            • 3. Re: How to define a process definition that has multiples su
              Pedro Alfaro Newbie

              I made the next changes but it don't work, it don't stop at the join node.
              Any ideas how to fix this?
              Thanks

              public class ForEachForkActionHandler implements ActionHandler
              {
               private static final long serialVersionUID = 1L;
               protected static final String FOREACH_PREFIX = "foreach.";
              
               /**
               * Create a new child token for each item in list.
               *
               * @param executionContext
               * @throws Exception
               */
               public void execute(final ExecutionContext executionContext) throws Exception
               {
               final Token rootToken = executionContext.getToken();
               final Node node = executionContext.getNode();
               final List argSets = new LinkedList();
              
               for (int i = 0; i < node.getLeavingTransitions().size(); i++) {
               final Transition transition = (Transition) node.getLeavingTransitions().get(0);
              
               for (int j = 0; j < 2; j++) {
              
               final Token newToken = new Token(rootToken, FOREACH_PREFIX + node.getId() + "." + j);
               newToken.setTerminationImplicit(true);
               executionContext.getJbpmContext().getSession().save(newToken);
              
               final ExecutionContext newExecutionContext = new ExecutionContext( newToken );
               newExecutionContext.getContextInstance().createVariable( "message", "data " + j, newToken);
               argSets.add(new Object[] {newExecutionContext, transition});
               }
               }
              
               for (int i = 0; i < argSets.size(); i++)
               {
               final Object[] args = (Object[]) argSets.get(i);
               node.leave((ExecutionContext) args[0], (Transition) args[1]);
               }
               }
              
              }
              
              
              <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="listingloads">
               <start-state name="load new file">
               <transition to="fork1">
               </transition>
               </start-state>
               <node name="fork1">
               <action class="com.ldg.bpm.handler.fork.ForEachForkActionHandler">
               </action>
               <transition name="subprocess" to="process-state1"></transition>
               </node>
               <node name="process-state1">
               <transition to="join1"></transition>
               </node>
               <join name="join1">
               <transition to="end"></transition>
               </join>
               <end-state name="end"></end-state>
              </process-definition>
              
              


              • 4. Re: How to define a process definition that has multiples su
                Ronald van Kuijk Master

                @faite That is (afaik) because the node is no waitstate. It continues immediately to it's default transition. So if you replace node by state, it should work and then eventually put the subprocess there.

                @Trouby: it's in the wiki.... like I mentioned.... faite could find it...

                • 5. Re: How to define a process definition that has multiples su
                  Pedro Alfaro Newbie

                  I am trying to use the sub-process but it don't work, some body said to download the source code and build the jbpm to make it work? That is true?,
                  because that is going to make everything slow to me.
                  there is a short way to fix this? there is a version I can download that work using sub-process node?
                  Please give me some help on this.

                  thanks

                  jbpm 3.2.2

                  • 7. Re: How to define a process definition that has multiples su
                    Pedro Alfaro Newbie

                    I changed the process definition

                    <process-definition xmlns="urn:jbpm.org:jpdl-3.2" name="listingloads">
                     <start-state name="load new file">
                     <transition to="fork1">
                     </transition>
                     </start-state>
                     <node name="fork1">
                     <action class="com.ldg.bpm.handler.fork.ForEachForkActionHandler">
                     </action>
                     <transition to="process-state2"></transition>
                     </node>
                     <process-state name="process-state2">
                     <sub-process name="processlistings"/>
                     <transition to="join1"></transition>
                     </process-state>
                     <join name="join1">
                     <transition to="end"></transition>
                     </join>
                     <end-state name="end"></end-state>
                    </process-definition>


                    Action
                    *********
                    public void execute(final ExecutionContext executionContext) throws Exception
                     {
                     final Token rootToken = executionContext.getToken();
                     final Node node = executionContext.getNode();
                     final List argSets = new LinkedList();
                    
                     for (int i = 0; i < node.getLeavingTransitions().size(); i++) {
                     final Transition transition = (Transition) node.getLeavingTransitions().get(0);
                    
                     for (int j = 0; j < 2; j++) {
                    
                     final Token newToken = new Token(rootToken, FOREACH_PREFIX + node.getId() + "." + j);
                    
                     newToken.setTerminationImplicit(true);
                     executionContext.getJbpmContext().getSession().save(newToken);
                    
                     final ExecutionContext newExecutionContext = new ExecutionContext( newToken );
                     newExecutionContext.getContextInstance().createVariable( "message", "data " + j, newToken);
                     argSets.add(new Object[] {newExecutionContext, transition});
                     }
                     }
                    
                     for (int i = 0; i < argSets.size(); i++)
                     {
                     final Object[] args = (Object[]) argSets.get(i);
                     node.leave((ExecutionContext) args[0], (Transition) args[1]);
                     }
                     }


                    And I get this error

                    11:08:45,020 ERROR [GraphElement] action threw exception: can't create a process instance when processDefinition is null
                    org.jbpm.JbpmException: can't create a process instance when processDefinition is null
                     at org.jbpm.graph.exe.ProcessInstance.<init>(ProcessInstance.java:129)
                     at org.jbpm.graph.exe.ProcessInstance.<init>(ProcessInstance.java:93)
                     at org.jbpm.graph.exe.Token.createSubProcessInstance(Token.java:621)
                     at org.jbpm.graph.node.ProcessState.execute(ProcessState.java:146)
                     at org.jbpm.graph.def.Node.enter(Node.java:314)
                     at sun.reflect.GeneratedMethodAccessor281.invoke(Unknown Source)
                     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
                     at java.lang.reflect.Method.invoke(Method.java:585)
                     at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:173)
                     at org.jbpm.graph.def.Node_$$_javassist_49.enter(Node_$$_javassist_49.java)
                     at org.jbpm.graph.def.Transition.take(Transition.java:151)
                     at org.jbpm.graph.def.Node.leave(Node.java:389)
                     at com.ldg.bpm.handler.fork.ForEachForkActionHandler.execute(ForEachForkActionHandler.java:52)


                    Could you help me to fix this?
                    Thanks

                    • 8. Re: How to define a process definition that has multiples su
                      Pedro Alfaro Newbie

                      I added the binding="late" attribute to the sub-process and now is working, it is going to be used to get the later version of my sub-process.
                      Thanks for your help

                      <process-state name="process-state2">
                       <sub-process name="processlistings" binding="late"/>
                       <transition to="join1"></transition>
                       </process-state>


                      • 9. Re: How to define a process definition that has multiples su
                        Jarkko Lietolahti Novice

                        Thanks!
                        This helped me also. The need for the binding="late" came after upgrading from JBoss ESB 4.4.GA to 4.5.GA. Before that there's no need for the it.