How to add task listener with parseUserTask for user task timeouts

Hi,

I have a simple process with 2 user task. When first user task timed out I want to execute task listener. But I don’t want to add listener to user task from Camunda Modeler. Therefore I am using parse listener, but TaskListener.EVENTNAME_TIMEOUT never triggers.

Here is bpmn:


Call_Activity_Process.bpmn (3.8 KB)

Here is parse listener code (Tried 3 different methods):

  @Override
    public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) {
        ActivityBehavior activityBehavior = activity.getActivityBehavior();

        if (activityBehavior instanceof UserTaskActivityBehavior){
            UserTaskActivityBehavior userTaskActivityBehavior = (UserTaskActivityBehavior) activityBehavior;
            TaskDefinition taskDefinition = userTaskActivityBehavior.getTaskDefinition();
            taskDefinition.addBuiltInTaskListener(TaskListener.EVENTNAME_TIMEOUT, new TimeoutListener());
            taskDefinition.addTaskListener(TaskListener.EVENTNAME_TIMEOUT,new TimeoutListener());
            taskDefinition.addTimeoutTaskListener("Timeout", new TimeoutListener());
        }
    }

TimeoutListener :

public class TimeoutListener implements TaskListener {
    private final Logger logger = LoggerFactory.getLogger(TimeoutListener.class);

    @Override
    public void notify(DelegateTask delegateTask) {
        logger.info("Task timed out! TaskId : " + delegateTask.getId() );
        System.out.println("Task timed out! TaskId : " + delegateTask.getId() );
    }
}

Hi @Mert_Mahanoglu

Depending on your use case and why you want to use a parse listener to add the task listener, you could consider a different approach.

If the task listener needs to be set dynamically at runtime, you could use beans to resolve the correct task listener. If you are running your application inside a Spring / CDI environment, you could have Spring / CDI injection framework produce the correct bean at run time and inside the Modeler, you set the task listener to use a Delegate Expression like ${taskListenerBeanName} - where taskListenerBeanName is - well the bean name of the task listener bean.

This way it can be left to Spring / CDI to create a bean everytime the task listener is executed. Fx for CDI, you could use a CDI producer method (@Produces) The bean must simply implement the TaskListener interface.

I hope that helps.

BR
Michael

Hi @mimaom,

Thanks for your comment. Your way about add listeners on timeout looks awesome. I will keep in my mind. But when a user task started/created I am able to add listener with code down delow. I wonder why listener is not executing in timeout event.

   @Override
    public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) {
        ActivityBehavior activityBehavior = activity.getActivityBehavior();

        if (activityBehavior instanceof UserTaskActivityBehavior){
            UserTaskActivityBehavior userTaskActivityBehavior = (UserTaskActivityBehavior) activityBehavior;
            TaskDefinition taskDefinition = userTaskActivityBehavior.getTaskDefinition();
            taskDefinition.addTaskListener(TaskListener.EVENTNAME_CREATE, new StartTaskListener());
            taskDefinition.addTaskListener(TaskListener.EVENTNAME_TIMEOUT, new TimeOutListener());
        }
    }

Also when timeout reaches if the boundary is interrupting I am able to run code on EVENTNAME_DELETE, but I don’t know is this the best way.

 taskDefinition.addTaskListener(TaskListener.EVENTNAME_DELETE, new TimeOutListener());

I can also run code when the timeout is as below. But I’m not the one to develop the bpmn model, so I want to make things easier with the parse listener.