Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: NPE fix when signal not found from model #3526

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

ikaakkola
Copy link
Contributor

In some rare cases the BpmnModel can change between the call to "containsSignalId" and the call to get the signal, causing an NPE if the signal was no longer available on the model.

Due to the way containsSignalId is implemented, the call to it is entirely unnecessary in these cases.

@@ -12,13 +12,13 @@
*/
package org.flowable.engine.impl.util;

import com.fasterxml.jackson.databind.node.ObjectNode;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please do not change the ordering of the imports from the standards for this project. See for example the top of this file: https://github.com/flowable/flowable-engine/blob/main/ide-settings/idea/idea-code-style-configuration.xml

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 thanks for the link, will update to match project code style.

In some rare cases the BpmnModel can change between the call to
"containsSignalId" and the call to get the signal, causing an NPE
if the signal was no longer available on the model.

Due to the way containsSignalId is implemented, the call to it
is entirely unnecessary in these cases.
@filiphr
Copy link
Contributor

filiphr commented Dec 20, 2022

@ikaakkola can you please provide some tests cases for this NPE? We would like to see why it fails.

@ikaakkola
Copy link
Contributor Author

@ikaakkola can you please provide some tests cases for this NPE? We would like to see why it fails.

I have not been able to reproduce this in unit tests, but have witnessed NPE in production for this ; that is, the BpmnModel signals were changed by another thread between the two calls (bpmnModel.containsSignalId() and the subsequent bpmnModel.getSignal() call) which is entirely possible as there is no synchronization of any sorts here.

The change simply removes the entirely unnecessary step of getting the signal twice - containsSignalId() calls provide no additional functionality as opposed to simply getting the signal and then checking if it was not null before using the signal.

It is very difficult to get this to happen in a junit test due to the fact that the BpmnModel needs to be changed between two subsequent function calls, but that doesn't mean it cannot happen.

@ikaakkola
Copy link
Contributor Author

Here is a stack trace showing this happen (Flowable 6.7.2) , the in-house ExtendedProcessRuntimeService.java parts are not really relevant here, the failure happens after calling org.flowable.engine.impl.RuntimeServiceImpl.startProcessInstanceById(using RuntimeService interface, not the Impl directly).

https://github.com/flowable/flowable-engine/blob/flowable-6.7.2/modules/flowable-engine/src/main/java/org/flowable/engine/impl/util/ProcessInstanceHelper.java#L415 (signal.getName() throws as signal is null)

Exception in thread "ProcessExecutor-1" org.flowable.common.engine.api.FlowableException: Exception during command execution
	at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:138)
	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.startProcessInstanceById(RuntimeServiceImpl.java:162)
	at com.qvantel.flex.bpmn.executor.service.process.ExtendedProcessRuntimeService.lambda$queueProcessWithId$6(ExtendedProcessRuntimeService.java:370)
	at org.flowable.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:67)
	at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:140)
	at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:114)
	at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:72)
	at org.flowable.engine.impl.interceptor.BpmnOverrideContextInterceptor.execute(BpmnOverrideContextInterceptor.java:26)
	at org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53)
	at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:105)
	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 com.qvantel.flex.bpmn.executor.service.process.ExtendedProcessRuntimeService.command(ExtendedProcessRuntimeService.java:156)
	at com.qvantel.flex.bpmn.executor.service.process.ExtendedProcessRuntimeService.lambda$queueProcessWithId$7(ExtendedProcessRuntimeService.java:365)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
	at org.flowable.engine.impl.util.ProcessInstanceHelper.handleSignalEventSubscription(ProcessInstanceHelper.java:415)
	at org.flowable.engine.impl.util.ProcessInstanceHelper.processEventSubProcess(ProcessInstanceHelper.java:348)
	at org.flowable.engine.impl.util.ProcessInstanceHelper.processAvailableEventSubProcesses(ProcessInstanceHelper.java:299)
	at org.flowable.engine.impl.util.ProcessInstanceHelper.startProcessInstance(ProcessInstanceHelper.java:280)
	at org.flowable.engine.impl.util.ProcessInstanceHelper.createAndStartProcessInstanceWithInitialFlowElement(ProcessInstanceHelper.java:257)
	at org.flowable.engine.impl.util.ProcessInstanceHelper.createProcessInstance(ProcessInstanceHelper.java:109)
	at org.flowable.engine.impl.cmd.StartProcessInstanceCmd.startProcessInstance(StartProcessInstanceCmd.java:239)
	at org.flowable.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:128)
	at org.flowable.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:53)
	at org.flowable.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:67)
	at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:140)
	at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:114)
	at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:72)
	at org.flowable.engine.impl.interceptor.BpmnOverrideContextInterceptor.execute(BpmnOverrideContextInterceptor.java:26)
	at org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53)
	at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:105)
	... 20 more

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants