cancel
Showing results for 
Search instead for 
Did you mean: 

activiti: task owner is deleted user

dirko
Champ in-the-making
Champ in-the-making
Hello,

I have the requirement that I need to periodically check whether the owner of a task is still a valid alfresco user. The approach I was looking at is the following:

- attach a timer to the task to be monitored
- the timer redirects to a serviceTask in which I test with a search.luceneSearch() whether the user still exists in alfresco

Now, the weird thing I observe is that the user that I delete (to be able to test this functionality) is recreated after this periodic task. My current (wild) guess is the the activiti machinery is somewhere calling personService.getPerson(deletedUser), which recreates this user.

When I set "<property name="createMissingPeople">false</property>" in authentication-services-context.xml to avoid this recreation of the deleted user, I obtain a transaction rollback (log below) and the workflow is stuck in the monitored task.

I know this is all rather vague, but I would be happy if someone could provide me with a hint on how to further investigate this or tell me whether there is a better approach to handling abandoned tasks.

dirk


13:49:23,245 ERROR [org.springframework.transaction.support.TransactionSynchronizationUtils] TransactionSynchronization.afterCompletion threw exception
java.lang.IllegalStateException: No value for key [org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@1003cac6] bound to thread [pool-9-thread-1]
        at org.springframework.transaction.support.TransactionSynchronizationManager.unbindResource(TransactionSynchronizationManager.java:199)
        at org.mybatis.spring.SqlSessionUtils$SqlSessionSynchronization.suspend(SqlSessionUtils.java:243)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.doSuspendSynchronization(AbstractPlatformTransactionManager.java:666)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.suspend(AbstractPlatformTransactionManager.java:569)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.handleExistingTransaction(AbstractPlatformTransactionManager.java:418)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction(AbstractPlatformTransactionManager.java:347)
        at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:127)
        at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:40)
        at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:33)
        at org.activiti.engine.impl.jobexecutor.DecrementJobRetriesListener.execute(DecrementJobRetriesListener.java:38)
        at org.activiti.spring.SpringTransactionContext$4.afterCompletion(SpringTransactionContext.java:82)
1 REPLY 1

dirko
Champ in-the-making
Champ in-the-making
Some additional info. I did a remote debug and I've set a breakpoint on personService.getPerson(String, boolean), which results in the stacktrace below. It is clear that something activiti related triggers this method: AlfrescoScriptDelegate(ActivitiScriptBase).getPersonNode. So currently this is recreating a removed user. Is this the desired behaviour? Wouldn't it be better to call the getPerson() version that does not recreate the user?

Thread [pool-9-thread-1] (Suspended (entry into method getPerson in PersonServiceImpl))   
   PersonServiceImpl.getPerson(String, boolean) line: 421   
   PersonServiceImpl.getPerson(String) line: 412   
   GeneratedMethodAccessor684.invoke(Object, Object[]) line: not available   
   DelegatingMethodAccessorImpl.invoke(Object, Object[]) line: 25   
   Method.invoke(Object, Object…) line: 597   
   AopUtils.invokeJoinpointUsingReflection(Object, Method, Object[]) line: 309   
   ReflectiveMethodInvocation.invokeJoinpoint() line: 183   
   ReflectiveMethodInvocation.proceed() line: 150   
   MethodSecurityInterceptor(MethodSecurityInterceptor).invoke(MethodInvocation) line: 80   
   ReflectiveMethodInvocation.proceed() line: 172   
   ExceptionTranslatorMethodInterceptor.invoke(MethodInvocation) line: 46   
   ReflectiveMethodInvocation.proceed() line: 172   
   AuditMethodInterceptor.invoke(MethodInvocation) line: 159   
   ReflectiveMethodInvocation.proceed() line: 172   
   TransactionInterceptor.invoke(MethodInvocation) line: 110   
   ReflectiveMethodInvocation.proceed() line: 172   
   JdkDynamicAopProxy.invoke(Object, Method, Object[]) line: 202   
   $Proxy89.getPerson(String) line: not available   
   AlfrescoScriptDelegate(ActivitiScriptBase).getPersonNode(String) line: 173   
   AlfrescoScriptDelegate(DelegateExecutionScriptBase).getInputMap(DelegateExecution, String) line: 98   
   AlfrescoScriptDelegate(DelegateExecutionScriptBase).runScript(DelegateExecution) line: 63   
   AlfrescoScriptDelegate.execute(DelegateExecution) line: 43   
   JavaDelegateInvocation.invoke() line: 34   
   JavaDelegateInvocation(DelegateInvocation).proceed() line: 37   
   DefaultDelegateInterceptor.handleInvocation(DelegateInvocation) line: 25   
   ServiceTaskJavaDelegateActivityBehavior.execute(DelegateExecution) line: 49   
   ServiceTaskJavaDelegateActivityBehavior.execute(ActivityExecution) line: 40   
   ClassDelegate.execute(ActivityExecution) line: 112   
   AtomicOperationActivityExecute.execute(InterpretableExecution) line: 40   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   AtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(InterpretableExecution) line: 48   
   AtomicOperationTransitionNotifyListenerStart(AbstractEventAtomicOperation).execute(InterpretableExecution) line: 52   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   AtomicOperationTransitionNotifyListenerStart(AbstractEventAtomicOperation).execute(InterpretableExecution) line: 45   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   AtomicOperationTransitionCreateScope.execute(InterpretableExecution) line: 44   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   AtomicOperationTransitionNotifyListenerTake.execute(InterpretableExecution) line: 61   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   AtomicOperationTransitionDestroyScope.execute(InterpretableExecution) line: 111   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   AtomicOperationTransitionNotifyListenerEnd.eventNotificationsCompleted(InterpretableExecution) line: 36   
   AtomicOperationTransitionNotifyListenerEnd(AbstractEventAtomicOperation).execute(InterpretableExecution) line: 52   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   AtomicOperationTransitionNotifyListenerEnd(AbstractEventAtomicOperation).execute(InterpretableExecution) line: 45   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   AtomicOperationTransitionDestroyScope.execute(InterpretableExecution) line: 109   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   AtomicOperationTransitionNotifyListenerEnd.eventNotificationsCompleted(InterpretableExecution) line: 36   
   AtomicOperationTransitionNotifyListenerEnd(AbstractEventAtomicOperation).execute(InterpretableExecution) line: 52   
   CommandContext.performOperation(AtomicOperation, InterpretableExecution) line: 76   
   ExecutionEntity.performOperation(AtomicOperation) line: 481   
   ExecutionEntity.take(PvmTransition) line: 326   
   ExecutionEntity.takeAll(List<PvmTransition>, List<ActivityExecution>) line: 420   
   BoundaryEventActivityBehavior.execute(ActivityExecution) line: 57   
   TimerExecuteNestedActivityJobHandler.execute(String, ExecutionEntity, CommandContext) line: 48   
   AuthenticatedTimerJobHandler$1.doWork() line: 91   
   AuthenticatedTimerJobHandler$1.doWork() line: 87   
   AuthenticationUtil.runAs(RunAsWork<R>, String) line: 529   
   AuthenticatedTimerJobHandler.execute(String, ExecutionEntity, CommandContext) line: 86   
   TimerEntity(JobEntity).execute(CommandContext) line: 78   
   TimerEntity.execute(CommandContext) line: 62   
   ExecuteJobsCmd.execute(CommandContext) line: 61   
   CommandExecutorImpl.execute(Command<T>) line: 24   
   CommandContextInterceptor.execute(Command<T>) line: 42   
   SpringTransactionInterceptor$1.doInTransaction(TransactionStatus) line: 42   
   TransactionTemplate.execute(TransactionCallback<T>) line: 130   
   SpringTransactionInterceptor.execute(Command<T>) line: 40   
   LogInterceptor.execute(Command<T>) line: 33   
   ExecuteJobsRunnable.run() line: 36   
   ThreadPoolExecutor$Worker.runTask(Runnable) line: 886   
   ThreadPoolExecutor$Worker.run() line: 908   
   Thread.run() line: 662