Here's what I'm thinking might work:
Get the list of NodeInstances for the process instance
For each node that is a HumanTaskNodeInstance get the workitemid for the node
Get the task using localTaskService.getTaskByWorkItemId(workitemid)
The best way to get this information is to use jbpm-bam module (basically it logs all the activities of your processes into a db) and to query NodeInstanceLog table.
This is a query you can use:
n.processInstanceId = :processInstanceId and
n.nodeName != ''
GROUP BY n.nodeName
HAVING MOD(COUNT(n), 2) = 1
We are using persistence and logging activity to the DB. We are trying to avoid directly querying the DB and sticking to using the API methods. Also from the query you suggest I don't see how that gives me the list active Tasks for the process instance which is what the use case I'm trying to implement requires.
AFAIK, there is no API to query history log.
jbpm-bam module inserts a row in NodeInstanceLog each time a node is entered and a different row each time a node is exited. What the query does is to check for odd occurences of a node (using its name) in NodeInstanceLog.
So, if the node is entered but not exited yet, you will have 1 row in NodeInstanceLog table for a particular process instance id and a particular node (assuming the names of your tasks are unique in a process). When the task is exited, a new row is inserted so the total number of rows for that particual node is even (not returned by the query). If it happens that the node is entered again (some kind of recursion in your process), then the row count will be odd again (3).
I implemented code which appears to work for a simple test case:
List<Task> activeTasks = new ArrayList<Task>();
StatefulKnowledgeSession ksession = createKnowledgeSession();
org.jbpm.task.TaskService localTaskService = this.getTaskService();
JPAWorkingMemoryDbLogger jpaLogger = new JPAWorkingMemoryDbLogger( ksession );
KnowledgeRuntimeLoggerFactory.newConsoleLogger( ksession );
WorkflowProcessInstance processInstance = (WorkflowProcessInstance) ksession.getProcessInstance( piId );
Collection<NodeInstance> nodes = processInstance.getNodeInstances();
for ( NodeInstance nodeInstance : nodes )
if( nodeInstance instanceof HumanTaskNodeInstance )
jbpmTask = localTaskService.getTaskByWorkItemId( ((HumanTaskNodeInstance) nodeInstance ).getWorkItemId() );
activeTasks.add( bpmTask );
You can also query the task service, something like
String query = select t from Task twhere t.taskData.status = org.jbpm.task.Status.Reserved and t.taskData.processInstanceId = <<pid>>
Isn't the query method deprecated? Is there another way to execute a custom query?
it must be possible. in the jbpm-console when you click the diagram button on a running process, it points to the current task.