cancel
Showing results for 
Search instead for 
Did you mean: 

How complete a workflow task from java ?

angello0571
Champ on-the-rise
Champ on-the-rise
Hello,

I need to complete a "task A" if after some time the user has not finished yet it. To do that, I am using a timer boundary event and when it fires I use a serviceTask to complete the "task A" with Java Code.

My first attempt was using WorkflowTaskQuery for getting the tasks related to my workflow instance:

String workflowInstanceId = String.valueOf(execution.getVariable("workflowinstanceid"));
         WorkflowService workflowService = serviceRegistry.getWorkflowService();
         WorkflowTaskQuery query = new WorkflowTaskQuery();
         query.setActive(true);
         query.setProcessId(workflowInstanceId);
         query.setTaskState(WorkflowTaskState.IN_PROGRESS);
         query.setOrderBy(new WorkflowTaskQuery.OrderBy[] {
         WorkflowTaskQuery.OrderBy.TaskId_Asc });
         List<WorkflowTask> tasks = workflowService.queryTasks(query);

After that I tried to update and complete the tasks returned by the workflowService in this way:

Map<QName, Serializable> props = task.getProperties();
            QName PROP_BPM_TASKID = QName.createQName("{http://www.alfresco.org/model/bpm/1.0}taskId");
            WorkflowTask tsk = workflowService.updateTask(task.getId(), props,null,null);
            workflowService.endTask(tsk.getId(), "flow2");
But I got an exception:

Exception in thread "pool-1-thread-1" java.lang.NullPointerException
   at org.alfresco.repo.workflow.activiti.properties.ActivitiPackagePropertyHandler.handlePackage(ActivitiPackagePropertyHandler.java:63)
   at org.alfresco.repo.workflow.activiti.properties.ActivitiPackagePropertyHandler.handleTaskProperty(ActivitiPackagePropertyHandler.java:49)
   at org.alfresco.repo.workflow.activiti.ActivitiTaskPropertyHandler.handleProperty(ActivitiTaskPropertyHandler.java:47)
   at org.alfresco.repo.workflow.WorkflowPropertyHandlerRegistry.handleVariablesToSet(WorkflowPropertyHandlerRegistry.java:75)
   at org.alfresco.repo.workflow.activiti.properties.ActivitiPropertyConverter.setTaskProperties(ActivitiPropertyConverter.java:759)
   at org.alfresco.repo.workflow.activiti.properties.ActivitiPropertyConverter.updateTask(ActivitiPropertyConverter.java:983)
   at org.alfresco.repo.workflow.activiti.ActivitiWorkflowEngine.updateTask(ActivitiWorkflowEngine.java:2094)
   at org.alfresco.repo.workflow.WorkflowServiceImpl.updateTask(WorkflowServiceImpl.java:773)
   at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
   at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
   at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
   at java.lang.reflect.Method.invoke(Method.java:597)
   at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:309)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
   at org.alfresco.repo.security.permissions.impl.AlwaysProceedMethodInterceptor.invoke(AlwaysProceedMethodInterceptor.java:34)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.security.permissions.impl.ExceptionTranslatorMethodInterceptor.invoke(ExceptionTranslatorMethodInterceptor.java:46)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.alfresco.repo.audit.AuditMethodInterceptor.invoke(AuditMethodInterceptor.java:147)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
   at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
   at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
   at $Proxy74.updateTask(Unknown Source)

I did a second attempt for completing the task using TaskService from Activiti API. This is how I tried:

   Map<QName, Serializable> props = task.getProperties();
            QName PROP_BPM_TASKID = QName.createQName("{http://www.alfresco.org/model/bpm/1.0}taskId");
            String taskId = String.valueOf(props.get(PROP_BPM_TASKID));
            taskService.complete(taskId);

But again I got another exception:

Exception in thread "pool-1-thread-1" org.apache.ibatis.exceptions.PersistenceException: 
### Error updating database.  Cause: org.postgresql.util.PSQLException: ERROR: inserción o actualización en la tabla «act_ru_variable» viola la llave foránea «act_fk_var_exe»
  Detail: La llave (execution_id_)=(62704) no está presente en la tabla «act_ru_execution».
### The error may involve org.activiti.engine.impl.persistence.entity.VariableInstanceEntity.insertVariableInstance-Inline
### The error occurred while setting parameters
### Cause: org.postgresql.util.PSQLException: ERROR: inserción o actualización en la tabla «act_ru_variable» viola la llave foránea «act_fk_var_exe»
  Detail: La llave (execution_id_)=(62704) no está presente en la tabla «act_ru_execution».
   at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:8)
   at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:120)
   at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:107)
   at org.activiti.engine.impl.db.DbSqlSession.flushInserts(DbSqlSession.java:420)
   at org.activiti.engine.impl.db.DbSqlSession.flush(DbSqlSession.java:347)
   at org.activiti.engine.impl.interceptor.CommandContext.flushSessions(CommandContext.java:147)
   at org.activiti.engine.impl.interceptor.CommandContext.close(CommandContext.java:103)
   at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:49)
   at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:42)
   at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:130)
   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.ExecuteJobsRunnable.run(ExecuteJobsRunnable.java:36)
   at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
   at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
   at java.lang.Thread.run(Thread.java:662)
Caused by: org.postgresql.util.PSQLException: ERROR: inserción o actualización en la tabla «act_ru_variable» viola la llave foránea «act_fk_var_exe»
  Detail: La llave (execution_id_)=(62704) no está presente en la tabla «act_ru_execution».
   at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2102)
   at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:1835)
   at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:257)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:512)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.executeWithFlags(AbstractJdbc2Statement.java:388)
   at org.postgresql.jdbc2.AbstractJdbc2Statement.execute(AbstractJdbc2Statement.java:381)
   at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)
   at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)
   at org.apache.commons.dbcp.DelegatingPreparedStatement.execute(DelegatingPreparedStatement.java:172)
   at org.apache.ibatis.executor.statement.PreparedStatementHandler.update(PreparedStatementHandler.java:22)
   at org.apache.ibatis.executor.statement.RoutingStatementHandler.update(RoutingStatementHandler.java:51)
   at org.apache.ibatis.executor.SimpleExecutor.doUpdate(SimpleExecutor.java:29)
   at org.apache.ibatis.executor.BaseExecutor.update(BaseExecutor.java:87)
   at org.apache.ibatis.executor.CachingExecutor.update(CachingExecutor.java:46)
   at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:118)

I am not sure if is possible to complete a task in a serviceTask fired by a timerBoundaryEvent. Does any body can help me how to do this in an appropiate way?

Thanks in advance.
2 REPLIES 2

mstein
Champ in-the-making
Champ in-the-making
I believe the timer event ends the task, and starts the task the timer event points too. My guess is that null pointer occurs because the task is already complete. If you have a listener that needs to fire, you'll have to duplicate the logic in the timeout script task, or move it out to script task that both the user task and the timer lead to.

mitpatoliya
Star Collaborator
Star Collaborator
You can surly do that in java.
But I think the "flow2" which you have mentioned might be wrong.
You need to specify one the possible transition name from the existing task.