NullPointerException on completion of JavaDelegate execution in Camunda 7.18 in essence the TimerEntity of the calculateRepeat method

I have a simple circuit consisting of a timer with a Cycle type and a cron value 0 5 * * * ?
I attached a photo of this scheme below.
image

This is followed by JavaDelegate, which downloads data from AD and performs some data manipulation. Heavy business logic is running, which runs in 23,000,000 milliseconds = 6.5 hours. Since the timer starts every hour, in order to avoid cases when the process is still running and the second one starts in parallel, I, inside the delegate used in the service-task, stop all parallel processes and give them to camunda with the status DONE

  public void pullAllScheduled() {
        if (!alreadyExecuted.compareAndSet(false, true)) {
            log.info("Импорт из АФ уже запущен, процесс завершен успешно.");
            return;
        }

        try {
            doImport();
        } catch (Exception ex) {
            log.error("Ошибка при выполнении импорта: {}", ex.getMessage(), ex);
        } finally {
            alreadyExecuted.set(false);
        }
    }

...
scheduleAudit.setProcessStatus(ScheduleAudit.Status.DONE);
...

I also attach my class implementing the JavaDelegate interface, its structure will be needed for further analysis

@Component("pullFactDelegate")
@AllArgsConstructor
@Slf4j
public class PullFactDelegate implements JavaDelegate {

    private FactScheduler factScheduler;
    private ScheduleAuditRepository scheduleAuditRepository;
    private RepositoryService repositoryService;

    @PostConstruct
    public void init() {
        log.info("PullFactDelegate создан и готов к использованию");
    }

    @Override
    public void execute(DelegateExecution execution) throws Exception {
        final ProcessDefinition processDefinition =
                repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(execution.getProcessDefinitionId())
                .singleResult();

        try {
            new ActivFactoringImportLogic(factScheduler,
                    scheduleAuditRepository).run(processDefinition.getId(),
                    processDefinition.getName(),
                    execution.getProcessInstanceId());
            log.info("Импорт завершен успешно");
        } catch (Exception e) {
            log.error("Ошибка импорта {}", e.getMessage(), e);
        }
    }
}

Regardless of the time it takes to complete the business logic, I get the log log.info (“Import completed successfully”);
Due to this, it can be concluded that my delegate is running successfully.
However, after receiving this log, I get an error from the keylock API. I attach the trace of the error in the screenshot format, unfortunately, I cannot send it in text

The last line contains the ID of a specific process, I will clarify that this is the ID of the original process. I mean, there is an initial process that started, in parallel with it, more instances of this process are trying to start, which I stop, I get an error for the initial process.

I have a duplicate process (the main process IDs are different) that does not have a timer and is started manually by the user. No matter how many times in a row I run this process, it always runs successfully. I assume that there is a problem with the timer, the error indicates this, but I can’t find the reason

Can you tell me where to look for the cause of the error?

Hi @Adrd2,

Killing a second running instance from within Java Delegate is not recommended. You can achieve the same with a cleaner model, In which the instance is ended by an end event only if it is a 2nd running instance.

Here is the expression used in “Query Process Instances Count”
#{execution.getProcessEngineServices().getRuntimeService().createProcessInstanceQuery().processDefinitionKey("test_process").count()}

Hi @Adrd2

Kindly find attached a simple working example.
Please note that user tasks are used just for illustration purposes.
test_process_v0.3.bpmn (6.6 KB)

Thank you for your advice. I changed my process based on your suggestion and the error from the screenshots really went away. Now TimerEntity does not throw an error, but camunda still throws optimisticLogicException after successful completion of the process, which is surprising - there is not a single place for such an error in the code that runs in ServiceTask. I apologize again for tracing the error in the form of a photo, but I can’t do otherwise. I’ll enable DEBUG mode and let you know if it turns out to be a CAMUNDA bug

Hi @Adrd2

Could you please share your process?
Do you have any parallel work going on in your model?
Can you please share the new implementation of your service task?

Of course, I attach the file of my business process
fact_cron (1).bpmn (5.9 KB)

Unfortunately, I can’t attach the full code of my delegate, the business logic executed in it is too big for the forum, but I will clarify a very important point - my business logic uses parallelStream only for data collection, then data is put into the base List from Java and work with it is carried out only using a regular stream.
I also think it will come in handy - the error occurs after I get the log log.info(“Импорт завершен успешно”); - the location of this log can be seen in the original question, this means that all business logic, including saving to the database, was successful

Testing takes a long time, as it doesn’t occur on all deployed stands. In the next few days, I will receive a detailed trace from the stand where the error occurs

Also, many other processes run in parallel with the process that causes the error, but they do not change the data that could cause such an error. Let me clarify that there are no errors when starting the process without a timer

Hi @Adrd2

Could you please try using the same logic I shared for implementing “Query Process Instances Count” task.

Use the same expression in the attached example except for the definition key (replace with yours)
#{execution.getProcessEngineServices().getRuntimeService().createProcessInstanceQuery().processDefinitionKey("test_process").count()}

1 Like

Hi, hassang.
Unfortunately, I must to use JavaDelegate to get count of runntime process, In the contour where the error occurs. As I see it, my delegate does the same thing as your request.

Delegate looks like this

@AllArgsConstructor
@Slf4j
@Component
public class CountStartedProcess implements JavaDelegate {

    @Override
    public void execute(DelegateExecution execution) throws Exception {
        String process = (String) execution.getVariable("process");

        log.debug("Process definition key: {}", process);

        long count = execution.getProcessEngineServices()
                .getRuntimeService()
                .createProcessInstanceQuery()
                .processDefinitionKey(process)
                .active()
                .count();

        log.debug("Count of runtime processes for {} is {}", process, count);

        execution.setVariable("count", count);
    }
}

The process id is passed to the process parameter

There are no errors in calculating the number of running processes, indeed, when one process is running, the second one does not start

Hi, @hassang
I received detailed logs in DEBUG mode from CAMUNDA, as I see there is an internal problem in CAMUNDA itself. The very first screenshot shows the time in milliseconds that the process took to complete. I also apologize for the format of the logs, but I cannot provide them in text. In total, there were 6 screenshots from the moment the business logic was completed to the error, but I can only attach one screenshot. In order not to spam, I will attach only a screenshot with the error itself, let me know if you need all the screenshots

and another one important screenshot