Set comment in task listener, got stackoverflow error

Hello,

I’m trying to set a comment through tasklistner. The very same listener works fine when I set it to “create” event but got stackoverflow error when I set it to “assignment” event.

Please kindly help to have a look.

Thank you very much!
Jimmy

*Please also ignore the business use case for a while, just want to understand why it doesn’t work.

Camunda version: Tomcat 7.17 (https://downloads.camunda.cloud/release/camunda-bpm/tomcat/7.17/camunda-bpm-tomcat-7.17.0.zip)
Diagram: created using modeler 5.2.0 from scratch.
DB: mssql 2014

Codes:

public class TestTaskListener implements TaskListener {
	@Override
	public void notify(DelegateTask task) {
		String comment = (String) task.getVariable("some_comments");
		if (comment == null) {
			comment = "(could not find a comment)";
		}
		System.out.println("task id=" + task.getId());
		System.out.println("Event name=" + task.getEventName());
		Comment a = task.getProcessEngineServices().getTaskService().createComment(task.getId(),
				task.getProcessInstanceId(), comment);
	}
}


process.bpmn (2.5 KB)

Hi Jimmy,

That’s an interesting observation.
The following seems to be happening: When the user task is assigned/claimed, your task listener is called. Now the trouble starts.

  1. The task listener updates the task via the task service (i.e., it creates a comment)
  2. The change raises an update event.
  3. Due to the update and the not yet completed assignment, a new assignment event is raised as well, which triggers your listener again and steps 1–3 are repeated over and over again until you get a stack overflow.

So, what to do?
I think the best would be to not change the task while you’re assigning it.

If you have to do it, you need to interrupt the infinite recursion. You can either…

  1. … check whether the task already has the comment - if so, complete the listener without updating the task or…
  2. … remember tasks that have been updated recently. If your task is among these recently updated tasks, do not update it again.

Probably, there are other ways of handling it all with the same outcome: you prevent the listener from being called more than once for the same task.

I hope that this helps, and I’m sorry that I cannot provide a more sophisticated solution.

1 Like

Hello Stephan,

Thanks a lot for the quick and detailed answer. No wonder sometimes the printed event type is “update”.

Thanks!
Jimmy

For those who got similar issue:
Thanks to Stephan’s comment I wouldn’t make any changes to task during assign or update event.
But if you have to, you may reference following implementation:
(not proved in production, just an idea)

public class TestTaskListener implements TaskListener {
	private static List<String> recent_changed = new ArrayList<String>();

	@Override
	public void notify(DelegateTask task) {
		try {
			System.out.println("task id=" + task.getId());
			System.out.println("Event name=" + task.getEventName());
			if (recent_changed.contains(task.getId())) {
				return;
			}
			String comment = (String) task.getVariable("some_comments");
			if (comment == null) {
				comment = "(could not find a comment)";
			}
			recent_changed.add(task.getId());
			task.getProcessEngineServices().getTaskService().createComment(task.getId(), task.getProcessInstanceId(),
					comment + "," + new Date());
		} finally {
			recent_changed.remove(task.getId());
		}
	}
}