08-19-2014 06:38 AM
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.delegate.event.ActivitiEvent;
import org.activiti.engine.delegate.event.ActivitiEventListener;
import org.activiti.engine.delegate.event.ActivitiEventType;
import org.activiti.engine.impl.bpmn.behavior.TaskActivityBehavior;
import org.activiti.engine.impl.pvm.delegate.ActivityExecution;
import org.activiti.engine.runtime.Execution;
import org.activiti.engine.runtime.ExecutionQuery;
public class ThreadDelegate extends TaskActivityBehavior {
@Override
public void execute(ActivityExecution execution) throws Exception {
System.out.println("Started thread delegate for execution id " + execution.getId());
Object counterObj = execution.getVariable("counter");
if(counterObj == null) {
execution.setVariable("counter", 0);
System.out.println("Counter initialised at 0");
} else {
int counter = (int) counterObj;
counter++;
execution.setVariable("counter", counter);
System.out.println("Counter incremented to " + counter);
}
final String executionId = execution.getId();
final Thread t = new Thread() {
@Override
public void run() {
System.out.println("Thread running");
// Forcing the thread to sleep causes the process the execute normally
// try {
// Thread.sleep(5000);
// } catch (InterruptedException e) { }
signalWaitState();
/* KLUDGE alert!
* This does work but I hope to achieve signalling without a polling loop.
*/
/*
int retries = 0;
while(retries < 5) {
try {
signalWaitState();
return;
} catch (NullPointerException e) {
retries++;
System.out.println("Waiting before retry " + retries);
try {
Thread.sleep(1000);
} catch (InterruptedException e2) { }
}
}
*/
}
/*
* Sometimes a NPE exception is thrown
* at org.activiti.engine.impl.persistence.entity.ExecutionEntity.signal(ExecutionEntity.java:375)
* unless the thread is forced to sleep first. Presumably this is because the wait state has not been
* executed yet.
*/
private void signalWaitState() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
runtimeService.signal(executionId);
System.out.println("Signalled exeuection id " + executionId);
}
};
/*
* The purpose of this event listener was to ensure that the waitState has been
* entered before starting the delegate thread. This was intended to prevent the
* intermittent NPE when called signal() when delegate thread completes execution.
*
* Even though the executionId is valid the query returns a null execution.
*/
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
runtimeService.addEventListener(new ActivitiEventListener() {
@Override
public void onEvent(ActivitiEvent event) {
RuntimeService runtimeService = event.getEngineServices().getRuntimeService();
System.out.println("Event type: " + event.getType() + " executionId: " + event.getExecutionId() + " piid: " + event.getProcessInstanceId());
// TODO: filter on executionId
try {
ExecutionQuery q = runtimeService.createExecutionQuery();
q.executionId(event.getExecutionId());
Execution execution = q.singleResult();
String activityId = execution.getActivityId();
System.out.println("Activity ID: " + activityId);
if("waitState".equals(activityId)) {
t.start();
}
System.out.println("Started delegate thread.");
} finally {
runtimeService.removeEventListener(this);
}
}
@Override
public boolean isFailOnException() {
return true;
}
});
this.leave(execution);
System.out.println("Left service task");
// Start the thread here unless using the event listener above
// t.start();
System.out.println("Started delegate thread.");
}
}
08-19-2014 07:28 AM
08-19-2014 07:42 AM
08-20-2014 01:58 PM
08-20-2014 02:00 PM
08-21-2014 09:16 AM
Tags
Find what you came for
We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.