1 2 Previous Next 21 Replies Latest reply on Jun 3, 2008 10:02 AM by Angel Scull

    Dynamic task creation

    Anonymous User Anonymous User Newbie

      Hi all
      I have a process named Interpello that, at a certains point, executes the task InizioInterpello.
      I attached at the node-leave event an action (actionIstruttoriaInterpello).

      This action have to create a task instance for a number of users (i mean a task that each selected user must execute).

      The code below (createAndAssignTask) does the work, but when the process arrives to the task ChiusuraInterpello, it should execute the action actionChiusuraInterpello (actually just display some outputs via println)
      but it doesn't execute nothing (I can't see the output), and the execution process doesn't step to verificaFinale.
      Everything goes well if I comment all the createAndAssignTask code invocation in the actionIstruttoriaInterpello

      There is something wrong in the code below (dynamic task creation)?

      thanks
      I'm using jbpm 3.1.2

      <?xml version="1.0" encoding="UTF-8"?>
      
      <process-definition
       xmlns="urn:jbpm.org:jpdl-3.1" name="Interpello">
       <swimlane name="startingUser">
       <assignment expression="variable(ThisProcessStartingUser)"></assignment>
       </swimlane>
       <start-state name="start">
       <transition name="" to="inizioInterpello"></transition>
       </start-state>
       <end-state name="end1"></end-state>
       <task-node name="verificaFinale">
       <task name="verifica finale" swimlane="startingUser"></task>
       <transition name="finito" to="end1"></transition>
       <transition name="ripeti" to="inizioInterpello"></transition>
       </task-node>
       <task-node name="inizioInterpello">
       <task name="inizio interpello" swimlane="startingUser"></task>
       <event type="node-leave">
       <action name="actionIstruttoriaInterpello" class="it.unict.interpello.IstruttoriaInterpello"></action>
       </event>
       <transition name="Convoca Interpello" to="chiusuraInterpello"></transition>
       </task-node>
       <task-node name="tCompDoc">
       </task-node>
       <task-node name="chiusuraInterpello">
       <task name="Chiusura interpello" swimlane="startingUser"></task>
       <event type="node-leave">
       <action name="actionChiudiInterpello" class="it.unict.interpello.ChiusuraInterpello"></action>
       </event>
       <transition name="procedi alla verifica finale" to="verificaFinale"></transition>
       </task-node>
      </process-definition>
      



       public void createAndAssignTask(String user, ExecutionContext executionContext)
       {
       Token token = null;
       TaskMgmtInstance tmi = null;
       TaskNode taskNode = null;
      
       try
       {
       token = executionContext.getToken();
       tmi = executionContext.getTaskMgmtInstance();
       taskNode = (TaskNode) executionContext.getNode();
      
       Task doCompilaDocumento = taskNode.getTask("tCompDoc");
       TaskInstance tCompDoc = tmi.createTaskInstance(doCompilaDocumento, token);
      
       tCompDoc.setName("consulta: convocazione " + user);
       tCompDoc.setActorId(user);
       tCompDoc.setCreate(token.getEnd());
      
       tCompDoc.setVariableLocally("XXX"+user, "");
       //tCompDoc.assign(executionContext);
       tmi.addTaskInstance(tCompDoc);
       System.out.println("creato: " + tCompDoc);
       } catch (Exception ex)
       {
       ex.printStackTrace();
       }
       }
      


        • 2. Re: Dynamic task creation
          Ronald van Kuijk Master

          if people do not respond, that could be because the info provided is to limited, or not really usable to try and reproduce.... just bumping often does not help

          • 3. Re: Dynamic task creation
            Anonymous User Anonymous User Newbie

            Thanks kukeltje, but I really don't know what information i omitted!

            Now I try to explain what I want to achieve, maybe someone can inspire me a new way.

            I want that, after a certain process task, each user in a set must execute a task.
            I don't know in advance how many users can be involved (i have a query to determine the set of users)
            this is why my process can't be fully designed in advance.

            any ideas?
            thanks

            • 4. Re: Dynamic task creation
              Ronald van Kuijk Master

              e.g. an 1 file executable unit test. instead of 1 method (it is not even a class file) and a process definition. This way I cannot even see if you made typos in the classname....

              Having one tasknode cannot be used for different actors. Use a custom fork for that and see the wiki for an example

              • 5. Re: Dynamic task creation
                Anonymous User Anonymous User Newbie

                I can't find any documentation on how to dinamically create a task instance at runtime. So the code below (and in previous post) is fruit of hours spend in trying ... I achieved something that (seems to) works. And this is the result.

                Maybe this is not the correct way, so any help needed!!


                <?xml version="1.0" encoding="UTF-8"?>
                
                <process-definition
                 xmlns="urn:jbpm.org:jpdl-3.1" name="Interpello">
                 <swimlane name="startingUser">
                 <assignment expression="user(admin)"></assignment>
                 </swimlane>
                 <start-state name="start">
                 <transition name="" to="inizioInterpello"></transition>
                 </start-state>
                 <end-state name="end1"></end-state>
                 <task-node name="verificaFinale">
                 <task name="verifica finale" swimlane="startingUser"></task>
                 <transition name="finito" to="end1"></transition>
                 <transition name="ripeti" to="inizioInterpello"></transition>
                 </task-node>
                 <task-node name="inizioInterpello">
                 <task name="inizio interpello" swimlane="startingUser"></task>
                 <event type="node-leave">
                 <action name="actionIstruttoriaInterpello" class="it.unict.interpello.IstruttoriaInterpello"></action>
                 </event>
                 <transition name="Convoca Interpello" to="chiusuraInterpello"></transition>
                 </task-node>
                 <task-node name="tCompDoc">
                 </task-node>
                 <task-node name="chiusuraInterpello">
                 <task name="Chiusura interpello" swimlane="startingUser"></task>
                 <event type="node-leave">
                 <action name="actionChiudiInterpello" class="it.unict.interpello.IstruttoriaInterpello"></action>
                 </event>
                 <transition name="procedi alla verifica finale" to="verificaFinale"></transition>
                 </task-node>
                 <process-state name="process1"></process-state>
                 <super-state name="super1"></super-state>
                </process-definition>



                as you can see in the xml, I created a node-leave action handler, and I call the same class (for testing purpose only) on leaving InizioInterpello and on leaving ChiusuraInterpello.

                Below you can read the code of the action handler.
                When I execute the InizioInterpello task the code is executed: I can see the output (System.out) and when I show the task list (context.getProcessInstance(processInstanceId).getTaskMgmtInstance().getTaskInstances()) of the process instance I see a task for every user.

                But If I execute ChiusuraInterpello I can't see no output, no new task instance were created ... it seems that my action is ignored at all. But the task is closed correctly.

                package it.unict.interpello;
                
                
                import it.unict.consulta.ManagerBeansProxy;
                import it.unict.consulta.driver.data.IDocente;
                import it.unict.consulta.driver.manager.IEducationManager;
                
                import java.util.Collection;
                
                import org.jbpm.graph.exe.ExecutionContext;
                import org.jbpm.graph.exe.Token;
                import org.jbpm.graph.node.TaskNode;
                import org.jbpm.taskmgmt.def.Task;
                import org.jbpm.taskmgmt.exe.TaskInstance;
                import org.jbpm.taskmgmt.exe.TaskMgmtInstance;
                
                public class IstruttoriaInterpello implements org.jbpm.graph.def.ActionHandler
                {
                 ManagerBeansProxy mbProxy = null;
                
                 public void execute(ExecutionContext executionContext) throws Exception
                 {
                System.out.println("qqqqq***********************************************************************");
                 System.out.println("*** I can see this only when leaving InizioInterpello, but nothing is shown when executing ChiusuraInterpello ***");
                 System.out.println("***********************************************************************");
                 System.out.println("***********************************************************************");
                 System.out.println("***********************************************************************");
                 System.out.println("***********************************************************************");
                
                 mbProxy = new ManagerBeansProxy();
                 IEducationManager edu = mbProxy.getMEducation();
                
                 if (edu == null)
                 throw new RuntimeException("EducationManager non disponibile");
                
                 try
                 {
                 // determine the sets of users
                 Collection<IDocente> lDoc = edu.listaDocenti();
                
                 if (lDoc == null || lDoc.size() == 0)
                 throw new RuntimeException("Nessun docente");
                
                 // for each user creates a personal task instance
                 for (IDocente d : lDoc)
                 {
                 String uname = d.getUsername();
                 createAndAssignTask(uname, executionContext);
                 }
                 }
                 catch (Exception ex)
                 {
                 System.out.println(ex);
                 createAndAssignTask("admin", executionContext);
                 }
                 }
                
                 public void createAndAssignTask(String user, ExecutionContext executionContext)
                 {
                 Token token = null;
                 TaskMgmtInstance tmi = null;
                 TaskNode taskNode = null;
                
                 try
                 {
                 token = executionContext.getToken();
                 tmi = executionContext.getTaskMgmtInstance();
                 taskNode = (TaskNode) executionContext.getNode();
                
                 // create the new task instance, a clone of tCompDoc
                 Task doCompilaDocumento = taskNode.getTask("tCompDoc");
                 TaskInstance tCompDoc = tmi.createTaskInstance(doCompilaDocumento, token);
                
                 // set the name of the task, the actor that this task is assigned to, and set the creation date
                 tCompDoc.setName("consulta: convocazione " + user);
                 tCompDoc.setActorId(user);
                 tCompDoc.setCreate(token.getEnd());
                
                 // build a variable
                 tCompDoc.setVariableLocally("XXX"+user, "");
                 // bind the newly created task instance to the task.
                 tmi.addTaskInstance(tCompDoc);
                 // print some outputs
                 System.out.println("***********************************************************************");
                 System.out.println("creato: " + tCompDoc);
                 System.out.println("***********************************************************************");
                 } catch (Exception ex)
                 {
                 ex.printStackTrace();
                 }
                 }
                
                }
                


                What you say about the fork is correct, I think. But Actually I don't know how to bind the newly created task instance to the rest of the process.
                Infact the code that create the task doesn't do this.

                Any idea on this?

                • 6. Re: Dynamic task creation
                  Ronald van Kuijk Master

                  this code is a little more and more info, however, I still cannot run it. The code that use the jbpm api etc is not there, so how you signal things etc is still not clear. So I cannot run it.

                  Look in the jbpm source to see how to write such unittests. It's so much easier to see express what you expect and so much easier for others to understand without having to write 'normal' sentences.

                  how to 'bind' new tasks to a process is in the example in the wiki....

                  • 7. Re: Dynamic task creation
                    Anonymous User Anonymous User Newbie

                    Actually I doesn't understand the problem.
                    All the above code is inside a par file.
                    You could test it by deploying the par on your jbpm engine.

                    Should I upload the par file here?

                    • 8. Re: Dynamic task creation
                      Anonymous User Anonymous User Newbie

                       

                      "kukeltje" wrote:
                      how to 'bind' new tasks to a process is in the example in the wiki....

                      can you post a link? I cant find the exact paragraph I need
                      thanks

                      • 9. Re: Dynamic task creation
                        Ronald van Kuijk Master

                        the custom fork example I mentioned before.

                        Google shows a lot of info when just searching for 'custom fork jbpm'. The wiki entry is on page 1!!! So that would not have cost you a lot of time. If you include 'wiki' in it it is even better.... *it's the FIRST hit in google...!!!!*

                        • 10. Re: Dynamic task creation
                          David Roberts Apprentice

                          I have only briefly thread through this thread (not much time right now sorry), so I'm not sure if I fully understand what your problem is. But, I managed to successfully create a number of Task Instances at runtime, so incase this will help you a bit, look at this thread where I posted my solution: http://www.jboss.com/index.html?module=bb&op=viewtopic&t=122524

                          • 11. Re: Dynamic task creation
                            Jim Tivy Newbie

                            I have the same problem you do. There is a short example in the User Guide in section 11.2.2. Task instances and graph execution that suggests task instances can be created - but it is somewhat poorly explained.
                            By the way, for my posting of today I found the dynamic fork did not seem to work since I need to add new tasks while the others are executing.

                            • 12. Re: Dynamic task creation
                              Anonymous User Anonymous User Newbie

                              I've tested the dleerob solution. But it doesn't works.

                              this is the image of the process i'm modelling
                              [img]http://web.tiscali.it/mcuccia/various/processimage.jpg[/img]

                              and this is the par file
                              http://web.tiscali.it/mcuccia/various/interpello.par

                              As you can see in this code

                               <node name="inizioInterpello">
                              
                               <event type="node-leave">
                               <action name="actionIstruttoriaInterpello" class="it.unict.interpello.IstruttoriaInterpello"></action>
                               </event>
                               <transition name="toFork" to="fork1"></transition>
                               </node>
                              

                              when the token leaves the inizioInterpello node I execute the action class IstruttoriaInterpello. This is the place where the new task instances are created.

                              Next you can see the relevant code of IstruttoriaInterpello: for each selected user, I create a new task, cloning "task compilazione".
                               TaskMgmtDefinition tmd = (TaskMgmtDefinition)executionContext.getDefinition(TaskMgmtDefinition.class);
                               Task task = tmd.getTask("task compilazione");
                               TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();
                               TaskInstance taskInstance = tmi.createTaskInstance(task, executionContext);
                               taskInstance.setActorId(user);
                              


                              BUT (here is the problem)
                              the newly created task has two leaving transictions named "tr1" and "tr2", and doesn't have the (aspected) leaving transiction named "toJoinFromCompilazione".

                              dleerob, do you have similar problems?
                              anyone knows why this appens?

                              thanks

                              PS sample at 11.2.2 http://docs.jboss.com/jbpm/v3/userguide/taskmanagement.html#taskinstancesandgraphexecution
                              is very very similar to the dleerob code

                              • 13. Re: Dynamic task creation
                                Angel Scull Newbie

                                Hello, i've the same problem but, in my case when i finish the FIRST of my task the execution continues through the fork-node and create one task per node after fork using ActionHandlers classes in node-enter event in that's nodes, but when i finish another task in the node before the fork-node the execution doesn't create any taskinstance

                                • 14. Re: Dynamic task creation
                                  Angel Scull Newbie

                                  hello massimiliano_cuccia
                                  I see you
                                  I recommend you, that you should create an ActionHandler and asosiate it with node-enter event in tasks nodes after fork-node

                                  1 2 Previous Next