Exception in Bproc unclaim

Hello,

we are having some issue with the unclaiming of Tasks.
The Stacktrace is:

    java.lang.NullPointerException: null
	at java.base/java.util.UUID.fromString(UUID.java:197) ~[na:na]
	at com.haulmont.addon.bproc.engine.eventlistener.UserTaskAssignedEventListener.findAssigneeUserOpt(UserTaskAssignedEventListener.java:58) ~[bproc-core-1.2.1.jar:na]
	at com.haulmont.addon.bproc.engine.eventlistener.UserTaskAssignedEventListener.onEvent(UserTaskAssignedEventListener.java:48) ~[bproc-core-1.2.1.jar:na]
	at org.flowable.common.engine.impl.event.FlowableEventSupport.dispatchNormalEventListener(FlowableEventSupport.java:114) ~[flowable-engine-common-6.5.0.jar:6.5.0]
	at org.flowable.common.engine.impl.event.FlowableEventSupport.dispatchEvent(FlowableEventSupport.java:108) ~[flowable-engine-common-6.5.0.jar:6.5.0]
	at org.flowable.common.engine.impl.event.FlowableEventSupport.dispatchEvent(FlowableEventSupport.java:99) ~[flowable-engine-common-6.5.0.jar:6.5.0]
	at org.flowable.common.engine.impl.event.FlowableEventDispatcherImpl.dispatchEvent(FlowableEventDispatcherImpl.java:65) ~[flowable-engine-common-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.util.TaskHelper.fireAssignmentEvents(TaskHelper.java:536) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.util.TaskHelper.changeTaskAssignee(TaskHelper.java:156) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.cmd.ClaimTaskCmd.execute(ClaimTaskCmd.java:73) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.cmd.ClaimTaskCmd.execute(ClaimTaskCmd.java:28) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.cmd.NeedsActiveTaskCmd.execute(NeedsActiveTaskCmd.java:58) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:51) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:93) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:72) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:56) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.interceptor.BpmnOverrideContextInterceptor.execute(BpmnOverrideContextInterceptor.java:25) ~[flowable-engine-6.5.0.jar:6.5.0]
	at org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53) ~[flowable-engine-common-6.5.0.jar:6.5.0]
	at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:72) ~[flowable-engine-common-6.5.0.jar:6.5.0]
	at org.flowable.common.spring.SpringTransactionInterceptor.lambda$execute$0(SpringTransactionInterceptor.java:56) ~[flowable-spring-common-6.5.0.jar:6.5.0]
	at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140) ~[spring-tx-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.flowable.common.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:56) ~[flowable-spring-common-6.5.0.jar:6.5.0]
	at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) ~[flowable-engine-common-6.5.0.jar:6.5.0]
	at com.haulmont.addon.bproc.engine.interceptor.BprocAuthenticationInterceptor.execute(BprocAuthenticationInterceptor.java:21) ~[bproc-core-1.2.1.jar:na]
	at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56) ~[flowable-engine-common-6.5.0.jar:6.5.0]
	at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51) ~[flowable-engine-common-6.5.0.jar:6.5.0]
	at org.flowable.engine.impl.TaskServiceImpl.unclaim(TaskServiceImpl.java:203) ~[flowable-engine-6.5.0.jar:6.5.0]
	at com.haulmont.addon.bproc.service.BprocTaskServiceBean.unclaim(BprocTaskServiceBean.java:94) ~[bproc-core-1.2.1.jar:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:344) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:198) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint.proceed(MethodInvocationProceedingJoinPoint.java:88) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at com.haulmont.cuba.core.sys.ServiceInterceptor.aroundInvoke(ServiceInterceptor.java:75) ~[cuba-core-7.2.18.jar:7.2.18]
	at jdk.internal.reflect.GeneratedMethodAccessor210.invoke(Unknown Source) ~[na:na]
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
	at java.base/java.lang.reflect.Method.invoke(Method.java:566) ~[na:na]
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:644) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:633) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:175) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:95) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212) ~[spring-aop-5.2.16.RELEASE.jar:5.2.16.RELEASE]
	at com.sun.proxy.$Proxy432.unclaim(Unknown Source) ~[na:na]
	at de.agentes.opm.service.bpmn.BpmnProzessSchrittServiceBean.aufgabeZuweisen(BpmnProzessSchrittServiceBean.java:224) ~[opm-core-6.0.1-SNAPSHOT.jar:na]

We are calliing the bprocTaskService.unclaim(taskId);
There is an exception thrown and cought, is this intended?
Our customers aren’t to happy about it beeing thrown.

Regards
Paul

Hello,

I noticed this
at de.agentes.opm.service.bpmn.BpmnProzessSchrittServiceBean.aufgabeZuweisen(BpmnProzessSchrittServiceBean.java:224) ~[opm-core-6.0.1-SNAPSHOT.jar:na]

some translation for others to understand: BpmnProzessSchrittServiceBean
Schritt = step
aufgabeZuweisen = assign task

Is it called/triggerd after you unclaimed the task? I think yes.
Could be that is why you get null instead of UUID of the task/process because after you unclaim(), the taskId becomes null inside your context and then you have bprocTaskService.unclaim(null) call?
If it is so, try to store the taskId into a variable before unclaim() and pass it to BpmnProzessSchrittServiceBean.aufgabeZuweisen

Kind regards,
Mladen

Hi Mladen,

the taskId is definitly not null. We double checked. It’s an error in the bproc.
In the UserTaskAssignedEventListener the method findAssigneeUserOpt is called with an String assignee, which in the case of unclaiming is null. In the method itself there is an UUID.fromString(assignee) which then throws the error.

regards
Paul

Hi,

It looks like a bug. I’ve created an issue for that. Thanks for reporting a problem.

As a workaround, you may override the UserTaskAssignedEventListener in your project:

public class MyUserTaskAssignedEventListener extends UserTaskAssignedEventListener {

    @Override
    protected Optional<User> findAssigneeUserOpt(String assignee) {
        if (Strings.isNullOrEmpty(assignee)) return Optional.empty();
        return super.findAssigneeUserOpt(assignee);
    }
}

Then register this bean in spring.xml:

    <bean id="bproc_UserTaskAssignedEventListener" class="com.company.demo.core.MyUserTaskAssignedEventListener"/>

Hello Maxim,

thanks, we’ll do that.