cancel
Showing results for 
Search instead for 
Did you mean: 

process terminated event?

m2spring
Champ in-the-making
Champ in-the-making
Is there a way I can register an event handler with the process engine to get called whenever a process finishes?
Currently I'm awkwardly polling the HistoryService for a given process ID to determine that a process finished.
Thanks!
-Max
3 REPLIES 3

frederikherema1
Star Contributor
Star Contributor
Look at http://activiti.org/userguide/index.html#executionListeners. You can easily add this to your BPMN file and allow any of your code to be run, once the process has been finished:


<process id="executionListenersProcess">
 
    <extensionElements>
      <activiti:executionListener class="org.activiti.examples.RecordProcessFinishedListener" event="end" />
    </extensionElements>

m2spring
Champ in-the-making
Champ in-the-making
Frederik, thank you for your response.
While I still find it kind of awkward to having to manipulate the BPMN DOM at BPMN load time just to get my listener injected, I got it now working.
I've got a helper which attaches the BPMN parse listener to the engine:

class JenkowEngine{

    static ProcessEngine getEngine(){
        if (engine == null){
            …
            ClassLoader peCL = JenkowEngine.class.getClassLoader();
            Thread.currentThread().setContextClassLoader(peCL);

            ProcessEngineConfigurationImpl peCfg = (ProcessEngineConfigurationImpl)cfg;
            List<BpmnParseListener> preParseListeners = peCfg.getPreParseListeners();
            if (preParseListeners == null){
                preParseListeners = new ArrayList<BpmnParseListener>();
                peCfg.setPreParseListeners(preParseListeners);
            }
            preParseListeners.add(new JenkowBpmnParseListener());
            cfg.setClassLoader(peCL);

            engine = cfg.buildProcessEngine();         
        }
        return engine;
    }
}
A new method adds the execution listener:

class JenkowBpmnParseListener extends AbstractBpmnParseListener{
    …
    @Override
    public void parseProcess(Element el, ProcessDefinitionEntity processDefinition) {
        processDefinition.addExecutionListener("end",new ProcessExecLogger(el.attribute("id")));
    }
}
The execution listener itself is the easy part.
(For some reason I'm unable to access the id of the process definition from DelegateExecution, I'm passing this around "by hand" as 'name'.)

public class ProcessExecLogger implements ExecutionListener{
    private String name;
   
    ProcessExecLogger(String name) {
        this.name = name;
    }

    @Override
    public void notify(DelegateExecution exec) throws Exception {
        System.out.println("name                          = "+name);
        System.out.println("exec.getEventName()          -> "+exec.getEventName());
        System.out.println("exec.getId()                 -> "+exec.getId());
        System.out.println("exec.getProcessBusinessKey() -> "+exec.getProcessBusinessKey());
        System.out.println("exec.getProcessInstanceId()  -> "+exec.getProcessInstanceId());
    }
}
It works, but does this make sense?
Thanks!
-Max

jbarrez
Star Contributor
Star Contributor
Looks good. That is exactly the use case why we added the bpmn parse listeners.