In about 60% cases can not resolve JavaDelegate in Service after Timer


#1

Hello dear!
I Have a problem, that in some cases(about 40%) After timer Process Engine cannot identify JavaDelegate in service task.
I don’t have any ideas.

I have the issue:

org.camunda.bpm.engine.ProcessEngineException: Unknown property used in expression: ${myCustomDelegate}. Cause: Cannot resolve identifier ‘myCustomDelegate’

I tried to set Java Class implementation field, but it didn’t work, too.

But in many cases it works…


ENGINE-09017 Cannot load class JavaDelegate for homogeneous cluster[RESOLVED]
#2

Are you using a single engine or a cluster?


#3

Hello @Niall.
I don’t really sure, That I understood what you mean about cluster.
I have Spring boot app with camunda spring boot starter and The second app, spring boot too, which has embedded process engine.


#4

So, you have 2 spring boot instances each with their own engine?
Are they connecting to the same database?


#5

@Niall, Yes, they have own engines and Yes, they are both connected to the same database.


#6

@romankh3, its homogeneous cluster setup with shared database, if Java Delegates are deployed to all of the nodes and all the nodes are with jobexecutor enabled. Otherwise it could be heterogeneous cluster steup.

Check whether its homogeneous or heterogeneous cluster. If it is heterogeneous cluster, then disable jobexecutor in the node which doesn’t have javaDelegates.

But i assume, the issue you are facing with javaDelgates is process engine not able to recognize.
In your BPMN file, try specifying fully Qualified class name of the java delegate.

For example,

com.workflow.delegates.order.SalesOrderDelegate

com.workflow.delegates.order -> Package name
SalesOrderDelegate -> JavaDelegate class name


#7

hello @aravindhrs!
According to your definition, I have the homogeneous cluster, because of the reason, that I have more than one instance of the application which is deployed this JavaDelegate.

About your assuming, I tried to change from Delegate Expression to Java Class implementation, as you wrote:

For example,
com.workflow.delegates.order.SalesOrderDelegate
com.workflow.delegates.order -> Package name
SalesOrderDelegate -> JavaDelegate class name

And I’ve reproduced this issue and have got the result, see below(I’ve changed the name of the real package):

    at org.camunda.bpm.engine.impl.util.EngineUtilLogger.exceptionWhileInstantiatingClass(EngineUtilLogger.java:78)
    at org.camunda.bpm.engine.impl.util.ClassDelegateUtil.instantiateDelegate(ClassDelegateUtil.java:50)
    at org.camunda.bpm.engine.impl.bpmn.behavior.ClassDelegateActivityBehavior.getActivityBehaviorInstance(ClassDelegateActivityBehavior.java:109)
    at org.camunda.bpm.engine.impl.bpmn.behavior.ClassDelegateActivityBehavior$1.call(ClassDelegateActivityBehavior.java:65)
    at org.camunda.bpm.engine.impl.bpmn.behavior.ClassDelegateActivityBehavior$1.call(ClassDelegateActivityBehavior.java:62)
    at org.camunda.bpm.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior.executeWithErrorPropagation(AbstractBpmnActivityBehavior.java:108)
    at org.camunda.bpm.engine.impl.bpmn.behavior.ClassDelegateActivityBehavior.execute(ClassDelegateActivityBehavior.java:62)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute$2.callback(PvmAtomicOperationActivityExecute.java:57)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute$2.callback(PvmAtomicOperationActivityExecute.java:46)
    at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.continueIfExecutionDoesNotAffectNextOperation(PvmExecutionImpl.java:1965)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute.execute(PvmAtomicOperationActivityExecute.java:38)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityExecute.execute(PvmAtomicOperationActivityExecute.java:27)
    at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:91)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:618)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:594)
    at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl$5.callback(PvmExecutionImpl.java:1904)
    at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl$5.callback(PvmExecutionImpl.java:1901)
    at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.continueExecutionIfNotCanceled(PvmExecutionImpl.java:1971)
    at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.dispatchDelayedEventsAndPerformOperation(PvmExecutionImpl.java:1920)
    at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.dispatchDelayedEventsAndPerformOperation(PvmExecutionImpl.java:1901)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(PvmAtomicOperationTransitionNotifyListenerStart.java:57)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(PvmAtomicOperationTransitionNotifyListenerStart.java:27)
    at org.camunda.bpm.engine.impl.core.operation.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:65)
    at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:91)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:69)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:629)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:604)
    at org.camunda.bpm.engine.impl.core.operation.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:58)
    at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:91)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:69)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:629)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:604)
    at org.camunda.bpm.engine.impl.core.operation.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:58)
    at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:91)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:618)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:594)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationTransitionCreateScope.scopeCreated(PvmAtomicOperationTransitionCreateScope.java:34)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationCreateScope.execute(PvmAtomicOperationCreateScope.java:50)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationCreateScope.execute(PvmAtomicOperationCreateScope.java:24)
    at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:91)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:112)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:618)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:594)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationActivityStartCancelScope.activityCancelled(PvmAtomicOperationActivityStartCancelScope.java:36)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationCancelActivity.execute(PvmAtomicOperationCancelActivity.java:60)
    at org.camunda.bpm.engine.impl.pvm.runtime.operation.PvmAtomicOperationCancelActivity.execute(PvmAtomicOperationCancelActivity.java:28)
    at org.camunda.bpm.engine.impl.interceptor.AtomicOperationInvocation.execute(AtomicOperationInvocation.java:91)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.invokeNext(CommandInvocationContext.java:125)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performNext(CommandInvocationContext.java:104)
    at org.camunda.bpm.engine.impl.interceptor.CommandInvocationContext.performOperation(CommandInvocationContext.java:79)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:618)
    at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:594)
    at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.executeActivity(PvmExecutionImpl.java:783)
    at org.camunda.bpm.engine.impl.pvm.runtime.PvmExecutionImpl.executeEventHandlerActivity(PvmExecutionImpl.java:583)
    at org.camunda.bpm.engine.impl.jobexecutor.TimerExecuteNestedActivityJobHandler.execute(TimerExecuteNestedActivityJobHandler.java:43)
    at org.camunda.bpm.engine.impl.jobexecutor.TimerExecuteNestedActivityJobHandler.execute(TimerExecuteNestedActivityJobHandler.java:27)
    at org.camunda.bpm.engine.impl.persistence.entity.JobEntity.execute(JobEntity.java:132)
    at org.camunda.bpm.engine.impl.cmd.ExecuteJobsCmd.execute(ExecuteJobsCmd.java:99)
    at org.camunda.bpm.engine.impl.cmd.ExecuteJobsCmd.execute(ExecuteJobsCmd.java:36)
    at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:24)
    at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:104)
    at org.camunda.bpm.engine.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
    at org.camunda.bpm.engine.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
    at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:66)
    at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
    at org.camunda.bpm.engine.impl.jobexecutor.ExecuteJobHelper.executeJob(ExecuteJobHelper.java:36)
    at org.camunda.bpm.engine.impl.jobexecutor.ExecuteJobHelper.executeJob(ExecuteJobHelper.java:29)
    at org.camunda.bpm.engine.impl.jobexecutor.ExecuteJobsRunnable.executeJob(ExecuteJobsRunnable.java:88)
    at org.camunda.bpm.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:57)
    at org.springframework.cloud.sleuth.instrument.async.TraceRunnable.run(TraceRunnable.java:62)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)
Caused by: org.camunda.bpm.engine.ClassLoadingException: ENGINE-09017 Cannot load class 'com.example.camunda.createrequest.DeleteDraftRequestDelegate': com.example.camunda.createrequest.DeleteDraftRequestDelegate
    at org.camunda.bpm.engine.impl.util.EngineUtilLogger.classLoadingException(EngineUtilLogger.java:135)
    at org.camunda.bpm.engine.impl.util.ReflectUtil.loadClass(ReflectUtil.java:107)
    at org.camunda.bpm.engine.impl.util.ClassDelegateUtil.instantiateDelegate(ClassDelegateUtil.java:42)
    ... 86 more
Caused by: java.lang.ClassNotFoundException: com.example.camunda.createrequest.DeleteDraftRequestDelegate
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:93)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at org.camunda.bpm.engine.impl.util.ReflectUtil.loadClass(ReflectUtil.java:84)
    ... 87 more```

#8

can you share the Java class for more clarification. it will be more easier to analyze


#9

Yes, it is not a problem.

import com.example.service.RequestService;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class DeleteDraftRequestDelegate implements JavaDelegate {

    private final RequestService requestService;

    @Autowired
    public DeleteDraftRequestDelegate(RequestService requestService) {
        this.requestService = requestService;
    }

    @Override
    public void execute(DelegateExecution delegateExecution) throws Exception {
        String businessKey = delegateExecution.getProcessBusinessKey();
        log.info("Delete draft request with business key #{} ", businessKey);
        Long requestId = Long.valueOf(businessKey);
        requestService.deleteDraft(requestId);
    }
}

#11

Hi @romankh3,

Abhishek struggeled with the same problems as you do. He had a talk at the CamundaCon about his solutions. Maybe it’s worth to watch: https://www.youtube.com/watch?v=Nx4I8lNMUs0

Hope this helps, Ingo


#12

I didn’t get why do you think that the package should be com.example.service.RequestService.DeleteDraftRequestDelegate?

It has another package:

com.example.camunda.createrequest.DeleteDraftRequestDelegate

Why do you think about removing constructor?
It works for about 50-60%. So How can removing this constructor change it?


#13

I didn’t said in the context of changing the package name. The input which I gave you was need to map the delegate class in the service task


#14

@aravindhrs, I’m sorry, but I have lost. Let’s try again.
I have class:

package com.example.camunda.createrequest;

import com.example.service.RequestService;
import lombok.extern.slf4j.Slf4j;
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.JavaDelegate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
@Slf4j
public class DeleteDraftRequestDelegate implements JavaDelegate {

    private final RequestService requestService;

    @Autowired
    public DeleteDraftRequestDelegate(RequestService requestService) {
        this.requestService = requestService;
    }

    @Override
    public void execute(DelegateExecution delegateExecution) throws Exception {
        String businessKey = delegateExecution.getProcessBusinessKey();
        log.info("Delete draft request with business key #{} ", businessKey);
        Long requestId = Long.valueOf(businessKey);
        requestService.deleteDraft(requestId);
    }
}

I have two instances and in 50% cases all works fine.


#15

Unfortunately, it has another cluster… On the conference describing heterogeneous cluster, on the other hand I have homogeneous cluster.


#16

diagram_1.bpmn (2.6 KB)

check the service task configured in attached bpmn.

It should be com.example.camunda.createrequest.DeleteDraftRequestDelegate


#17

Hi @romankh3,

I don’t think that you have a homogeneous cluster. From the description above and the fact that you are facing a ClassNotFoundException, this class is only available in one of your spring-boot applications.

For me it seems that you have a heterogeneous cluster.

But you can extract the delegation logic into a seperate project and use this in both spring-boot applications.

Hope this helps, Ingo


#18

@Ingo_Richtsmeier, I think it because of the reason that I have two instances of the same application. They are the same so they have the same JavaDelegates.

Am I wrong?


#19

@aravindhrs, I checked, it is like you wrote.


#20

Did you create both spring-boot apps with the same pom.xml?


#21

@Ingo_Richtsmeier, yes it’s one spring-boot app, which has two instances,
so yes. it has the same pom.xml, too.