-
1. Re: Advice regarding complex proccess modeling
saraswati.santanu Nov 6, 2009 4:26 AM (in response to fabiomsouto)Hi,
did you consider using Assignment handler?
If you implement "Read Document" as a task node and add an assignment handler to it, which can execute whatever business logic it needs to, to decide whether X, Y or Z or all of them or none of them can do "Read" task.... <task name="read" > <assignment-handler class="org.jbpm.examples.ReadAssignTask"> </assignment-handler> <transition to="decide" /> </task> <decision name="decide"> <handler class="org.jbpm.examples.DecideWhatToDo" /> <transition name="read again" to="read" /> <transition name="read done" to="next node" /> </decision> ...
-
2. Re: Advice regarding complex proccess modeling
fabiomsouto Nov 10, 2009 6:44 AM (in response to fabiomsouto)Hi,
Thank you for your reply. It was helpful.
We are using the Assignment Handler right now.
Now we would like to create several instances of the 'Review' task, one for each user. How can we garantee that the next task will only start executing when all of the 'Review' tasks are done? We are using jBPM4. -
3. Re: Advice regarding complex proccess modeling
fabiomsouto Nov 10, 2009 7:10 AM (in response to fabiomsouto)Sorry for double posting. Is it possible to do this using a custom ActivityBehaviour?
-
4. Re: Advice regarding complex proccess modeling
saraswati.santanu Nov 10, 2009 11:05 AM (in response to fabiomsouto)How about creating sub-tasks in you actual task? Signalling flag will be false for the sub-tasks by default. So it will not transit to the next node till you call complete on the super task.
The following code may be used when the review task becomes activeTask reviewTask = taskService.createTaskQuery() .activityName("Review") .processInstanceId(processInstanceId) .uniqueResult(); for (String userId:userIds) { TaskImpl subTask = reviewTask.createTask("Review for user "+userId) .addCandidateUser(userId); reviewTask.addSubTask(subTask); }
When an user performs review then you can execute something like this://somehow get the review task Task reviewTask = taskService.createTaskQuery() .activityName("Review") .processInstanceId(processInstanceId) .uniqueResult(); //some get the sub task for this user Task reviewSubTask = taskService.createTaskQuery() .activityName("Review for user "+userId) .processInstanceId(processInstanceId) .uniqueResult(); //complete the sub task taskService.completeTask(reviewSubTask.getId()); //remove sub task from the super task reviewTask.removeSubTask(reviewSubTask); //if there exists not sub task then move on if (reviewTask.getSubTasks().isEmpty()) { taskService.completeTask(reviewTask.getId()); }
This is just an idea I got now. I have never tried this. So the code may not be accurate. Let me know if it works.
You may need to create a node altogether if you need to implement your own activity behaviour. You cannot really assign your own behaviour to the existing Task node of Jbpm. This also can be an approach to solve this problem. -
5. Re: Advice regarding complex proccess modeling
fabiomsouto Nov 20, 2009 4:55 AM (in response to fabiomsouto)Thank you for your help. It has helped us a lot to think a bit more and know jbpm.
We are trying to follow a similar solution to yours, but, when we try to create a new subtask on a task, an exception occurs:09:41:12,935 SEV | [BaseJbpmTestCase] TEST THROWS EXCEPTION: no environment to get org.jbpm.pvm.internal.session.DbSession org.jbpm.api.JbpmException: no environment to get org.jbpm.pvm.internal.session.DbSession at org.jbpm.pvm.internal.env.EnvironmentImpl.getFromCurrent(EnvironmentImpl.java:197) at org.jbpm.pvm.internal.env.EnvironmentImpl.getFromCurrent(EnvironmentImpl.java:190) at org.jbpm.pvm.internal.task.TaskImpl.createSubTask(TaskImpl.java:231) at org.jbpm.pvm.internal.task.TaskImpl.createSubTask(TaskImpl.java:243) at org.teste.TratarDoc.testTratarDoc(TratarDoc.java:63) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at junit.framework.TestCase.runTest(TestCase.java:164) at org.jbpm.test.BaseJbpmTestCase.runTest(BaseJbpmTestCase.java:80) at junit.framework.TestCase.runBare(TestCase.java:130) at junit.framework.TestResult$1.protect(TestResult.java:106) at junit.framework.TestResult.runProtected(TestResult.java:124) at junit.framework.TestResult.run(TestResult.java:109) at junit.framework.TestCase.run(TestCase.java:120) at junit.framework.TestSuite.runTest(TestSuite.java:230) at junit.framework.TestSuite.run(TestSuite.java:225) at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:130) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) ### EXCEPTION ###########################################
The piece of code is the followingfor (String responsavel : responsaveis) { TaskImpl subTask = tratarTask.createSubTask("Tratar para" + responsavel); subTask.setAssignee(responsavel); taskService.saveTask(subTask); tratarTask.addSubTask(subTask); }
It goes mad when we call createSubTask(). What are we doing wrong? :-( -
6. Re: Advice regarding complex proccess modeling
saraswati.santanu Dec 2, 2009 12:21 AM (in response to fabiomsouto)Hi,
This is a pretty late response. Out on a trip an could not access for few days.
The way you are creating sub tasks may not work. You should use command service to get your job done instead of using direct methods on tasks. Command service will ensure all the interceptors are invoked before a call is made to your command. One such interceptor will create a DBSession for you. A sample code should look like this:Task task = //get the parent task somehow //create a new task which is a child of the task above Task subTask = taskService.newTask(task.getId()); subTask.setName(subTaskName); //this is important as this call will add this task to the sub task //set of the parent task. I believe this should have been done //during the previous call, but atleast now, it does not happen ((TaskImpl)task).addSubTask((TaskImpl)subTask);
Also there is a method in taskService to get sub tasks of a task, try using that when you need to get the sub tasks. -
7. Re: Advice regarding complex proccess modeling
siva_movva Dec 9, 2009 10:52 PM (in response to fabiomsouto)Hi,
Is there a similar API in JBPM3 that allows subTask creation for an existing task?
Any help would be appreciated. -
8. Re: Advice regarding complex proccess modeling
kukeltje Dec 10, 2009 1:33 PM (in response to fabiomsouto)no, not a similar api. You have to do it low level
-
9. Re: Advice regarding complex proccess modeling
mihai007 Feb 25, 2010 5:51 AM (in response to saraswati.santanu)any idea about how to be notified when a subtask ends?
I mean I define a task in process xml, then an assignment handler for the task. There I set assignee as null and create 2 subtasks each assigned to a different user.
When the users complete the subtask I would like to be notified so that I could close the main task and so the process goes on.
In xml is easy, I just do:
<on event="end"> <event-listener class="ABC" /> </on>
But how can I add such an event to a subtask that was created during run-time?
P.S: having a timer to check endlessly for subtasks end does not count as it is not a viable solution.
Oh and using the jbpm 4.3 with the solution presented by Santanu Saraswati to create the sub tasks
-
10. Re: Advice regarding complex proccess modeling
frankee787 Jun 1, 2011 2:41 AM (in response to saraswati.santanu)How would it be possible to do the same thing in jBPM5 ?