NullPointerException in AtomicOperationTransitionDestroyScope
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-18-2014 03:50 AM
In activiti 5.16.3 we defined a flow that has a receive task.
Later on in the flow it is possible to be redirected to that same receive task.
In our integration tests we test the flow by signalling the execution
Since it is possible in our flow that the same recieve task needs to notified twice we signal it again.
Due to an oversight on our part we did this without waiting for the process to be in the correct waiting state.
This gives us a strange exception:
By adding the check to verify if the process is waiting we can avoid the exception.
But it took us a while to find out what was wrong, you don't expect nullpointers like that.
Also troubling was the fact that it seemed to break all of the running activiti process.
Other integration tests suddenly also failed.
Update:
Entering Thread.sleep in our test code seems to resolve it
But that's not an ideal solution.
Any idea's?
Later on in the flow it is possible to be redirected to that same receive task.
In our integration tests we test the flow by signalling the execution
runtimeService.signal(id, processData);
Since it is possible in our flow that the same recieve task needs to notified twice we signal it again.
Due to an oversight on our part we did this without waiting for the process to be in the correct waiting state.
This gives us a strange exception:
Caused by: java.lang.NullPointerException: null at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionDestroyScope.execute(AtomicOperationTransitionDestroyScope.java:96) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:96) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:621) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:616) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyListenerEnd.eventNotificationsCompleted(AtomicOperationTransitionNotifyListenerEnd.java:35) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:56) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:96) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:621) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:616) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:49) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:96) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:621) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:616) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.persistence.entity.ExecutionEntity.take(ExecutionEntity.java:440) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.persistence.entity.ExecutionEntity.take(ExecutionEntity.java:418) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.bpmn.behavior.BpmnActivityBehavior.performOutgoingBehavior(BpmnActivityBehavior.java:131) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.bpmn.behavior.BpmnActivityBehavior.performDefaultOutgoingBehavior(BpmnActivityBehavior.java:64) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.bpmn.behavior.FlowNodeActivityBehavior.leave(FlowNodeActivityBehavior.java:44) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.bpmn.behavior.AbstractBpmnActivityBehavior.leave(AbstractBpmnActivityBehavior.java:47) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.bpmn.behavior.ReceiveTaskActivityBehavior.signal(ReceiveTaskActivityBehavior.java:35) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.persistence.entity.ExecutionEntity.signal(ExecutionEntity.java:397) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.cmd.SignalCmd.execute(SignalCmd.java:43) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.cmd.NeedsActiveExecutionCmd.execute(NeedsActiveExecutionCmd.java:55) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:24) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:57) ~[activiti-engine-5.16.3.jar:5.16.3] at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47) ~[activiti-spring-5.16.3.jar:5.16.3] at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:131) ~[spring-tx-3.2.8.RELEASE.jar:3.2.8.RELEASE]
By adding the check to verify if the process is waiting we can avoid the exception.
But it took us a while to find out what was wrong, you don't expect nullpointers like that.
Also troubling was the fact that it seemed to break all of the running activiti process.
Other integration tests suddenly also failed.
Update:
Entering Thread.sleep in our test code seems to resolve it
But that's not an ideal solution.
Any idea's?
Labels:
- Labels:
-
Archive
2 REPLIES 2
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-13-2015 05:40 AM
In Activiti 5.17 we still encounter this:
We wait for the process to wait for the event before we send the message.
We do this by querying the proces so that it is in the receive task before we send the message.
<code>
runtimeService.createExecutionQuery()
.processDefinitionKey(processDefinitionKey)
.activityId(taskIdentifier)
.processVariableValueEquals(A_KEY, aUniqueValue);
</code>
When this query returns the result we signal the process that the task is received. But this still gives us the error.
<code>
Caused by: java.lang.NullPointerException: null
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionDestroyScope.execute(AtomicOperationTransitionDestroyScope.java:96) ~[activiti-engine-5.17.0.jar:5.17.0]
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:96) ~[activiti-engine-5.17.0.jar:5.17.0]
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:631) ~[activiti-engine-5.17.0.jar:5.17.0]
</code>
If we add the ugly:
<code>Thread.sleep(1000);</code>
then our tests pass.
But i really don't want such fragile tests with Thread.sleeps everywhere.
We wait for the process to wait for the event before we send the message.
We do this by querying the proces so that it is in the receive task before we send the message.
<code>
runtimeService.createExecutionQuery()
.processDefinitionKey(processDefinitionKey)
.activityId(taskIdentifier)
.processVariableValueEquals(A_KEY, aUniqueValue);
</code>
When this query returns the result we signal the process that the task is received. But this still gives us the error.
<code>
Caused by: java.lang.NullPointerException: null
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionDestroyScope.execute(AtomicOperationTransitionDestroyScope.java:96) ~[activiti-engine-5.17.0.jar:5.17.0]
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:96) ~[activiti-engine-5.17.0.jar:5.17.0]
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:631) ~[activiti-engine-5.17.0.jar:5.17.0]
</code>
If we add the ugly:
<code>Thread.sleep(1000);</code>
then our tests pass.
But i really don't want such fragile tests with Thread.sleeps everywhere.
Options
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
05-18-2015 10:56 AM
That is a racing condition between the receive task database commit and the signal method.
I agree a nullpointer is not nice, but it would still be the same issue with a nicer message.
If you signal that quickly, why not use another construct (a custom service task for example that does the wait and receive at once?)
I agree a nullpointer is not nice, but it would still be the same issue with a nicer message.
If you signal that quickly, why not use another construct (a custom service task for example that does the wait and receive at once?)
