Why does Camunda attempt to execute a task listener in the wrong process engine?

Hello!

I have three Camunda engines using a shared database:

There is starter_wrapper_process.bpmn in core-workflow. This process starts WrapperProcess.bpmn defined in core-processes. Finally, WrapperProcess.bpmn starts DomainProcess.bpmn from domain-hello-world engine.

When

  1. WrapperProcess.bpmn starts DomainProcess.bpmn and
  2. DomainProcess.bpmn completes (i. e. execution returns to WrapperProcess.bpmn),

I want to execute a certain piece of code before a domain process starts and after it ends

This piece of code must be located in core-processes and the developers of domain-hello-world must be able to create and run their processes without ever thinking about this piece of code.

Therefore the activity Start domain process has two task listeners (tab Listeners) which are supposed to execute DomainProcessStartFinishTaskListener before the domain process starts and after it finishes.

Since this listener is referenced from and defined in core-processes I assume that it will run in core-processes (provided all engines run in deployment-aware mode).

But it doesn’t.

Let’s say I launch all three engines and start Starter Process via the task list. In the console output I see DomainProcessStartFinishTaskListener.notify which means that the start listener has been executed successfully.

Next, I go to the task list and complete the human task.

Now something unexpected happens: An incident occurs in the instance of DomainProcess.bpmn inside the domain-hello-world engine:

ENGINE-09008 Exception while instantiating class 'org.example.DomainProcessStartFinishTaskListener': ENGINE-09017 Cannot load class 'org.example.DomainProcessStartFinishTaskListener': org.example.DomainProcessStartFinishTaskListener

Full stack trace is available here.

At the bottom of it, you see a ClassNotFoundException:

Caused by: org.camunda.bpm.engine.ClassLoadingException: ENGINE-09017 Cannot load class 'org.example.DomainProcessStartFinishTaskListener': org.example.DomainProcessStartFinishTaskListener
	at org.camunda.bpm.engine.impl.util.EngineUtilLogger.classLoadingException(EngineUtilLogger.java:146)
	at org.camunda.bpm.engine.impl.util.ReflectUtil.loadClass(ReflectUtil.java:111)
	at org.camunda.bpm.engine.impl.util.ClassDelegateUtil.instantiateDelegate(ClassDelegateUtil.java:46)
	... 187 more
Caused by: java.lang.ClassNotFoundException: org.example.DomainProcessStartFinishTaskListener

This is understandable – org.example.DomainProcessStartFinishTaskListener is defined in core-processes (not in domain-hello-world).

What I cannot understand is why it is domain-hello-world that tries to execute the task listener which is referenced in BPMN file that is located in core-processes. DomainProcess does not contain any task listeners and does not refer to org.example.DomainProcessStartFinishTaskListener.

Question: How do I need to modify my code in order for org.example.DomainProcessStartFinishTaskListener to always be executed in core-processes (both before the domain process starts and after it ends)?

Thanks in advance

Dmitrii Pisarenko

Hi Dimitri,

when running Camunda in a heterogeneous cluster, the engines should be configured as deployment aware.

You can have a look at our documentation:

https://docs.camunda.org/manual/7.15/user-guide/process-engine/the-job-executor/#job-execution-in-heterogeneous-clusters

Hope that helps,
Manu

1 Like

Thanks for your answer.

the engines should be configured as deployment aware.

They are.

If you look at application.yaml files of

you will find the configuration

camunda.bpm:
...
  job-execution:
    deployment-aware: true

in each of those files.

Hi Dimitri,

Seems like your repo is private, so I cannot follow the shared links :frowning:

Kind Regards,
Manu

2 Likes

Hi, Manu!

That’s Dmitrii from my private account.

I made the repo public couple of minutes ago. Please try again.

Thanks!

Dmitrii

Hi @Dmitrii_Pisarenko : The reason is that the CallActivity “Start Domain Process” has an “Asnyc Before” but no “Async After” configured. Therefore the engine that runs the User Task tries to execute the EndListener.
Best, McAlm

3 Likes

Hello, McAlm!

Thanks for your answer.

I added “Async After” in the activity “Start Domain Process” in this commit. It did not solve the problem.

Best regards

Dmitrii

FYI: I set async-beforeand async-after for all activities in this commit. The error still occurs.

Hi @Dmitrii_Pisarenko : Yes, true, and now I know why… The EndListener is part of the current transaction which is the one executed on the DomainProcess. An additional job (Async After the Call Activity) does not affect the current transaction nor does it when you introduce an AsyncAfter at the EndEvent of DomainProcess, as this job then belongs to the DomainProcess, too.
I’m afraid that this problem cannot be solved, the only way is to move the listener to the outgoing sequence flow or to a ServiceTask. The Async After the CallActivity is then definitely needed.

Best, McAlm