Forum post: https://forum.camunda.org/t/nullpointerexception-while-completing-a-task/5454
Hi,
we are trying to switch to camunda 7.8 but we are facing a NPE while trying to complete a UserTask via REST-API. The reason why this happens is rather curious:
We registered a taskNotificationListener which sends notifications via websockets when a task gets completed (via taskService.getIdentityLinksForTask(delegateTask.getId())). This method uses the GetIdentityLinksForTaskCmd which programmatically adds a new IdentityLinkObject to the IdentityList. Thankfully the comment in this method already explains the NPE. Camunda then tries to complete and delete this task with all associated Identitylinks (TaskManager:L84). Since everything happens in the same thread, the TaskEntity is already cached in dbEntityCache AND the (dirty) List with IdentityLinkEntities is already loaded. An IdentityLinkEntity with ID [NULL] gets passed to the DbOperationsManager and the underlying DbEntityOperationComparator where it goes Boom. I’ve added the relevant code and the stacktrace below…
the execute method in GetIdentityLinksForTaskCmd loads the IdentityLinks and adds a new Entity with ID [NULL] to the List.
List<IdentityLink> identityLinks = (List) task.getIdentityLinks(); // assignee is not part of identity links in the db. // so if there is one, we add it here. // @Tom: we discussed this long on skype and you agreed ;-) // an assignee *is* an identityLink, and so must it be reflected in the API // // Note: we cant move this code to the TaskEntity (which would be cleaner), // since the task.delete cascased to all associated identityLinks // and of course this leads to exception while trying to delete a non-existing identityLink if (task.getAssignee() != null) { IdentityLinkEntity identityLink = new IdentityLinkEntity(); identityLink.setUserId(task.getAssignee()); identityLink.setTask(task); identityLink.setType(IdentityLinkType.ASSIGNEE); identityLinks.add(identityLink); } if (task.getOwner() != null) { IdentityLinkEntity identityLink = new IdentityLinkEntity(); identityLink.setUserId(task.getOwner()); identityLink.setTask(task); identityLink.setType(IdentityLinkType.OWNER); identityLinks.add(identityLink); } return (List) task.getIdentityLinks();
TaskEntity.getIdentityLinks() does not reload its IdentityLinks once initalized, so the dirty IdentityLinkEntity stays in the List
public List<IdentityLinkEntity> getIdentityLinks() { if (!isIdentityLinksInitialized) { taskIdentityLinkEntities = Context .getCommandContext() .getIdentityLinkManager() .findIdentityLinksByTaskId(id); isIdentityLinksInitialized = true; } return taskIdentityLinkEntities; }
NPE-Stacktrace
Caused by: java.lang.NullPointerException: null at java.lang.String.compareTo(String.java:1155) ~[na:1.8.0_74] at org.camunda.bpm.engine.impl.db.entitymanager.operation.comparator.DbEntityOperationComparator.compare(DbEntityOperationComparator.java:35) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.db.entitymanager.operation.comparator.DbEntityOperationComparator.compare(DbEntityOperationComparator.java:24) ~[camunda-engine-7.8.0.jar:7.8.0] at java.util.TreeMap.put(TreeMap.java:552) ~[na:1.8.0_74] at java.util.TreeSet.add(TreeSet.java:255) ~[na:1.8.0_74] at org.camunda.bpm.engine.impl.db.entitymanager.operation.DbOperationManager.addOperation(DbOperationManager.java:75) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.db.entitymanager.DbEntityManager.performEntityOperation(DbEntityManager.java:572) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.db.entitymanager.DbEntityManager.flushCachedEntity(DbEntityManager.java:451) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.db.entitymanager.DbEntityManager.flushEntityCache(DbEntityManager.java:417) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.db.entitymanager.DbEntityManager.flush(DbEntityManager.java:283) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:203) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.interceptor.CommandContext.close(CommandContext.java:132) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:113) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42) ~[camunda-engine-spring-7.8.0.jar:7.8.0] at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133) ~[spring-tx-4.3.12.RELEASE.jar:4.3.12.RELEASE] at org.camunda.bpm.engine.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40) ~[camunda-engine-spring-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.interceptor.ProcessApplicationContextInterceptor.execute(ProcessApplicationContextInterceptor.java:66) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.impl.TaskServiceImpl.complete(TaskServiceImpl.java:173) ~[camunda-engine-7.8.0.jar:7.8.0] at org.camunda.bpm.engine.rest.sub.task.impl.TaskResourceImpl.complete(TaskResourceImpl.java:96) ~[camunda-engine-rest-core-7.8.0.jar:7.8.0] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_74] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_74] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_74] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_74]
A solution for this issue would be returning a copy of List<IdentityLinkEntity> with the dirty entity in the GetIdentityForTaskCmd.
Cheers,
Jürgen
This is the controller panel for Smart Panels app
- is related to
-
CAM-14730 Buggy behavior of DelegateTask related to identity-links
- Closed