holunda-io / camunda-bpm-taskpool

Library for pooling user tasks and process related business objects.
https://www.holunda.io/camunda-bpm-taskpool/
Apache License 2.0
67 stars 26 forks source link

ProcessDefinitionService.getProcessDefinitions(...) throws NullpointerException #862

Closed S-Tim closed 1 year ago

S-Tim commented 1 year ago

Steps to reproduce

When a process definition that can only be started using message correlation (no regular start event) is deployed in Camunda and picked up by Polyflow (RefreshProcessDefinitionsJobCommand : EVENTING-021: New process definition detected. Sending the command for test_process.), the ProcessDefinitionService tries to get the start form key of the process definition (ProcessDefinitionService:53)

return newDefinitions.map { it.asCommand(applicationName = collectorProperties.applicationName, formKey = formService.getStartFormKey(it.id)) }

This then propagates to the GetFormKeyCmd in Camunda where

FormDefinition formDefinition = processDefinition.getStartFormDefinition();

returns null and therefore

formKeyExpression = formDefinition.getFormKey();

throws a NullPointerException

Expected behaviour

The expected behaviour would be to only get the start form key if one is available.

Actual behaviour

It is always attempted to retrieve the start form key.

2023-09-06 13:54:25.585 ERROR 44944 --- [aTaskExecutor-1] org.camunda.bpm.engine.context           : ENGINE-16004 Exception while closing command context: Cannot invoke "org.camunda.bpm.engine.impl.form.FormDefinition.getFormKey()" because "formDefinition" is null

java.lang.NullPointerException: Cannot invoke "org.camunda.bpm.engine.impl.form.FormDefinition.getFormKey()" because "formDefinition" is null
    at org.camunda.bpm.engine.impl.cmd.GetFormKeyCmd.execute(GetFormKeyCmd.java:84) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.cmd.GetFormKeyCmd.execute(GetFormKeyCmd.java:40) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:28) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:110) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.spring.SpringTransactionInterceptor.lambda$execute$0(SpringTransactionInterceptor.java:71) ~[camunda-engine-spring-7.18.6-ee.jar:7.18.6-ee]
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.27.jar:5.3.27]
    at org.camunda.bpm.engine.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:71) ~[camunda-engine-spring-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:70) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.CommandCounterInterceptor.execute(CommandCounterInterceptor.java:35) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.ExceptionCodeInterceptor.execute(ExceptionCodeInterceptor.java:55) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.FormServiceImpl.getStartFormKey(FormServiceImpl.java:99) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at io.holunda.polyflow.taskpool.collector.process.definition.ProcessDefinitionService.getProcessDefinitions(ProcessDefinitionService.kt:53) ~[polyflow-camunda-bpm-taskpool-collector-3.14.3.jar:3.14.3]
    at io.holunda.polyflow.taskpool.collector.process.definition.RefreshProcessDefinitionsJobHandler.execute(RefreshProcessDefinitionsEventingJobHandler.kt:32) ~[polyflow-camunda-bpm-taskpool-collector-3.14.3.jar:3.14.3]
    at io.holunda.polyflow.taskpool.collector.process.definition.RefreshProcessDefinitionsJobHandler.execute(RefreshProcessDefinitionsEventingJobHandler.kt:20) ~[polyflow-camunda-bpm-taskpool-collector-3.14.3.jar:3.14.3]
    at org.camunda.bpm.engine.impl.persistence.entity.JobEntity.execute(JobEntity.java:133) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.cmd.ExecuteJobsCmd.execute(ExecuteJobsCmd.java:110) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.cmd.ExecuteJobsCmd.execute(ExecuteJobsCmd.java:43) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.CommandExecutorImpl.execute(CommandExecutorImpl.java:28) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:110) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.spring.SpringTransactionInterceptor.lambda$execute$0(SpringTransactionInterceptor.java:71) ~[camunda-engine-spring-7.18.6-ee.jar:7.18.6-ee]
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.3.27.jar:5.3.27]
    at org.camunda.bpm.engine.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:71) ~[camunda-engine-spring-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:70) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.CommandCounterInterceptor.execute(CommandCounterInterceptor.java:35) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.interceptor.ExceptionCodeInterceptor.execute(ExceptionCodeInterceptor.java:55) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.jobexecutor.ExecuteJobHelper.executeJob(ExecuteJobHelper.java:57) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.jobexecutor.ExecuteJobsRunnable.executeJob(ExecuteJobsRunnable.java:110) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at org.camunda.bpm.engine.impl.jobexecutor.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:71) ~[camunda-engine-7.18.6-ee.jar:7.18.6-ee]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) ~[na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) ~[na:na]
    at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]

Fix

Polyflow already has the ProcessDefinitionEntity in the ProcessDefinitionService which has a getter for checking whether a start form key exists or not (.hasStartFormKey()). This could be used to only call

formService.getStartFormKey(it.id)

if the getter has returned true and otherwise just set the formKey to null directly