After upgrading from Flowable 6.4.2 to 6.5.0, existing processes that have an Event Subprocess with an Error End Event and Boundary Error Event have started throwing NullPointerExceptions when processing the Boundary Error Event.
Here’s a sample bpmn which exhibits the change in behavior between 6.4.2 and 6.5.0
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
<process id="test_error_boundary" name="test error boundary" isExecutable="true">
<startEvent id="startEvent1" flowable:formFieldValidation="true"></startEvent>
<exclusiveGateway id="sid-DDC2CF19-5BBC-4A96-A065-BE514CF16CE4"></exclusiveGateway>
<sequenceFlow id="sid-E9156686-9C87-441B-8FF1-948CCA6769AA" sourceRef="startEvent1" targetRef="sid-DDC2CF19-5BBC-4A96-A065-BE514CF16CE4"></sequenceFlow>
<serviceTask id="sid-F3A95B3F-46E3-440D-81C2-3DADFE31D1F1" flowable:delegateExpression="${throwingDelegate}"></serviceTask>
<sequenceFlow id="sid-2588468D-8D2E-4E7E-9606-0374A3F970FC" sourceRef="sid-DDC2CF19-5BBC-4A96-A065-BE514CF16CE4" targetRef="sid-F3A95B3F-46E3-440D-81C2-3DADFE31D1F1"></sequenceFlow>
<endEvent id="sid-9C9DF9C1-13CD-4845-923B-D18614C7046A"></endEvent>
<sequenceFlow id="sid-F594B58C-9C7D-476B-901B-BD5BC6AC3EE8" sourceRef="sid-F3A95B3F-46E3-440D-81C2-3DADFE31D1F1" targetRef="sid-9C9DF9C1-13CD-4845-923B-D18614C7046A"></sequenceFlow>
<subProcess id="error_sub_process" name="Error Sub Process" triggeredByEvent="true">
<startEvent id="sid-233FE319-A488-4A2C-9EAE-EB2F36904983" isInterrupting="true">
<errorEventDefinition errorRef="restClientError"></errorEventDefinition>
</startEvent>
<exclusiveGateway id="sid-ED4F9F87-4F76-492F-8352-9E800782EC21"></exclusiveGateway>
<endEvent id="sid-C1610AD2-A69A-4FE9-97AF-90F7C77DCA03">
<errorEventDefinition errorRef="handledError"></errorEventDefinition>
</endEvent>
<sequenceFlow id="sid-482147B9-1DC2-42CC-A75E-AEF07E45EAB0" sourceRef="sid-233FE319-A488-4A2C-9EAE-EB2F36904983" targetRef="sid-ED4F9F87-4F76-492F-8352-9E800782EC21"></sequenceFlow>
<sequenceFlow id="sid-9096CCD1-A495-4871-8D80-BCCB51398CE8" sourceRef="sid-ED4F9F87-4F76-492F-8352-9E800782EC21" targetRef="sid-C1610AD2-A69A-4FE9-97AF-90F7C77DCA03"></sequenceFlow>
</subProcess>
<sequenceFlow id="sid-448398F9-17DB-4795-81D2-FBB49B748E3D" sourceRef="sid-15467FC7-B823-474F-9E68-C35CAA5B3328" targetRef="sid-9C9DF9C1-13CD-4845-923B-D18614C7046A"></sequenceFlow>
<boundaryEvent id="sid-15467FC7-B823-474F-9E68-C35CAA5B3328" attachedToRef="error_sub_process">
<errorEventDefinition errorRef="handledError"></errorEventDefinition>
</boundaryEvent>
</process>
</definitions>
The java delegate is a simple delegate which throws a BPMNError:
public class ThrowingDelegate implements JavaDelegate {
@Override
public void execute(DelegateExecution execution) {
throw new BpmnError("restClientError");
}
}
In Flowable 6.4.2, the process completes successfully, however when the process is executed in 6.5.0 the following exception is thrown:
2020-03-18 21:14:37.728 ERROR 11 --- [qtp247944893-16] o.f.c.e.impl.interceptor.CommandContext : Error while closing command context
java.lang.NullPointerException: null
at org.flowable.engine.impl.agenda.AbstractOperation.getCurrentFlowElement(AbstractOperation.java:53)
at org.flowable.engine.impl.agenda.TriggerExecutionOperation.run(TriggerExecutionOperation.java:52)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:88)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:72)
at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:56)
at org.flowable.engine.impl.interceptor.BpmnOverrideContextInterceptor.execute(BpmnOverrideContextInterceptor.java:25)
at org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53)
at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:72)
at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:51)
at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56)
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51)
at org.flowable.engine.impl.RuntimeServiceImpl.startProcessInstance(RuntimeServiceImpl.java:732)
at org.flowable.engine.impl.runtime.ProcessInstanceBuilderImpl.start(ProcessInstanceBuilderImpl.java:205)
at org.flowable.engine.impl.RuntimeServiceImpl.startProcessInstanceWithForm(RuntimeServiceImpl.java:171)
at org.flowable.ui.task.service.runtime.FlowableProcessInstanceService.startNewProcessInstance(FlowableProcessInstanceService.java:132)
at org.flowable.ui.task.service.runtime.FlowableProcessInstanceService$$FastClassBySpringCGLIB$$6558533.invoke(<generated>)
at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:769)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:366)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:99)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:747)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:689)
at org.flowable.ui.task.service.runtime.FlowableProcessInstanceService$$EnhancerBySpringCGLIB$$6b32ef7f.startNewProcessInstance(<generated>)
at org.flowable.ui.task.rest.runtime.ProcessInstancesResource.startNewProcessInstance(ProcessInstancesResource.java:33)
I’ve tracked it down to the following within ErrorPropagation#executeEventHander
where the double starred condition is what fails causing boundaryExecution
to be null
childExecution.getActivityId()
= sid-C1610AD2-A69A-4FE9-97AF-90F7C77DCA03
event.getId()
= sid-15467FC7-B823-474F-9E68-C35CAA5B3328
} else {
ExecutionEntity boundaryExecution = null;
List<? extends ExecutionEntity> childExecutions = parentExecution.getExecutions();
for (ExecutionEntity childExecution : childExecutions) {
if (childExecution != null
&& childExecution.getActivityId() != null
&& **childExecution.getActivityId().equals(event.getId()))** {
boundaryExecution = childExecution;
}
}
CommandContextUtil.getAgenda().planTriggerExecutionOperation(**boundaryExecution**);
The question is, should something change in the BPMN or was a bug introduced in Flowable 6.5? Nothing other than the version of Flowable changed. I also tested the same scenario using end escalation events and boundary escalation events with the same results. Clearly I’m doing something wrong here, but I’m not sure what that is. Any suggestions would be greatly appreciated.
Thanks in advance.