0

I'm trying to add a listener in my file.bpmn to detect if I've arrived to the endEvent :

<process id="workflow" name="workflow" isExecutable="true">
    <extensionElements>

 <activiti:eventListener class="ActivitiProcessEndListener" />
    </extensionElements>
    <startEvent id="startEvent1"></startEvent>

my ActivitiProcessEndListener implements ActivitiEventListener after executing my circuit i have the following error:

o.a.e.d.event.impl.ActivitiEventSupport  : Exception while executing event-listener, which was ignored

java.lang.StackOverflowError: null
    at org.apache.ibatis.reflection.MetaObject.getValue(MetaObject.java:113)
    at org.apache.ibatis.scripting.xmltags.DynamicContext$ContextMap.get(DynamicContext.java:94)
    at org.apache.ibatis.scripting.xmltags.DynamicContext$ContextAccessor.getProperty(DynamicContext.java:108)
    at org.apache.ibatis.ognl.OgnlRuntime.getProperty(OgnlRuntime.java:2434)
    at org.apache.ibatis.ognl.ASTProperty.getValueBody(ASTProperty.java:114)
    at org.apache.ibatis.ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
    at org.apache.ibatis.ognl.SimpleNode.getValue(SimpleNode.java:258)
    at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:494)
    at org.apache.ibatis.ognl.Ognl.getValue(Ognl.java:458)
    at org.apache.ibatis.scripting.xmltags.OgnlCache.getValue(OgnlCache.java:44)
    at org.apache.ibatis.scripting.xmltags.ExpressionEvaluator.evaluateIterable(ExpressionEvaluator.java:43)
    at org.apache.ibatis.scripting.xmltags.ForEachSqlNode.apply(ForEachSqlNode.java:55)
    at org.apache.ibatis.scripting.xmltags.MixedSqlNode.apply(MixedSqlNode.java:33)
    at org.apache.ibatis.scripting.xmltags.DynamicSqlSource.getBoundSql(DynamicSqlSource.java:41)
    at org.apache.ibatis.mapping.MappedStatement.getBoundSql(MappedStatement.java:280)
    at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:80)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:120)
    at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:113)
    at org.activiti.engine.impl.db.DbSqlSession.selectListWithRawParameter(DbSqlSession.java:440)
    at org.activiti.engine.impl.db.DbSqlSession.selectList(DbSqlSession.java:431)
    at org.activiti.engine.impl.persistence.entity.ExecutionEntityManager.findProcessInstanceByQueryCriteria(ExecutionEntityManager.java:140)
    at org.activiti.engine.impl.ProcessInstanceQueryImpl.executeList(ProcessInstanceQueryImpl.java:597)
    at org.activiti.engine.impl.AbstractQuery.executeSingleResult(AbstractQuery.java:183)
    at org.activiti.engine.impl.AbstractQuery.execute(AbstractQuery.java:166)
    at org.activiti.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:24)
    at org.activiti.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:57)
    at org.activiti.spring.SpringTransactionInterceptor$1.doInTransaction(SpringTransactionInterceptor.java:47)
    at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
    at org.activiti.spring.SpringTransactionInterceptor.execute(SpringTransactionInterceptor.java:45)
    at org.activiti.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:31)
    at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:40)
    at org.activiti.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:35)
    at org.activiti.engine.impl.AbstractQuery.singleResult(AbstractQuery.java:129)
    at ActivitiProcessEndListener.onEvent(ActivitiProcessEndListener.java:62)
    at org.activiti.engine.impl.bpmn.helper.DelegateActivitiEventListener.onEvent(DelegateActivitiEventListener.java:45)

this is my listener :

public class ActivitiProcessEndListener implements ActivitiEventListener {
@Override


public void onEvent(final ActivitiEvent event) {

     if (event.getType() == ActivitiEventType.PROCESS_COMPLETED || event.getType() == ActivitiEventType.PROCESS_CANCELLED
                || event.getType() == ActivitiEventType.PROCESS_COMPLETED_WITH_ERROR_END_EVENT) {
            ActivitiEntityEvent aee = (ActivitiEntityEvent) event;
            LOGGER.info(String.format("Instance evt, type [%s], id=[%s], processDefinitionId=[%s]", event.getType(), event.getProcessInstanceId(), event.getProcessDefinitionId()));
            if (event.getProcessInstanceId() != null) {
                ProcessInstance procInst = event.getEngineServices().getRuntimeService().createProcessInstanceQuery().processInstanceId(event.getProcessInstanceId()).singleResult();
                Task task = event.getEngineServices().getTaskService().createTaskQuery().executionId(event.getExecutionId()).singleResult();
                if (task == null) {
                    task = event.getEngineServices().getTaskService().createTaskQuery().processInstanceId(event.getProcessInstanceId()).singleResult();
                }
                if (task == null) {
                    LOGGER.debug("No task ");
                }
                WfTaskInstance tskInst = new WfTaskInstance(task, aee);
                tskInst.setBusinessKey(procInst.getBusinessKey());
                Map<String, Object> variables = event.getEngineServices().getRuntimeService().getVariables(event.getExecutionId());
                String codeCircuit = event.getProcessDefinitionId().substring(0, event.getProcessDefinitionId().indexOf(":"));
                WfBusinessMethodsRegistry.getInstance().callBusinessMethod(codeCircuit, tskInst, variables);
            }

            return;
        }

            if (event.getProcessInstanceId() != null) {
                ProcessInstance procInst = event.getEngineServices().getRuntimeService().createProcessInstanceQuery().processInstanceId(event.getProcessInstanceId()).singleResult();

                if (procInst != null && procInst.getActivityId() != null && "EndEvent".equalsIgnoreCase(procInst.getActivityId())) {
                    Long sId = (Long) event.getEngineServices().getRuntimeService().getVariable(event.getExecutionId(), "id");

                    final String queryStr = "UPDATE table SET  DATE = :date WHERE id = :id";

                    final EntityManager entityManager = EntityManagerFactoryRegistry.INSTANCE.getNamedEntityManagerFactory("Persistence").createEntityManager();
                    final Query query = entityManager.createNativeQuery(queryStr);
                    query.setParameter("date", LocalDate.now());
                    query.setParameter("id", sId);
                    query.executeUpdate();

                }
            }
        }



        }

the problem is in this line :

ProcessInstance procInst = event.getEngineServices().getRuntimeService().createProcessInstanceQuery().processInstanceId(event.getProcessInstanceId()).singleResult();

i have modified my listener like this but i have an error in query.executeUpdate()

@Override
public void notify(DelegateExecution execution) throws Exception {
        Long sId= (Long) execution.getVariable("Id");

        final String queryStr = "UPDATE table SET  DATE = :date WHERE id = :id";

        final EntityManager entityManager = EntityManagerFactoryRegistry.INSTANCE.getNamedEntityManagerFactory("Persistence").createEntityManager();
        final Query query = entityManager.createNativeQuery(queryStr);
                query.setParameter("date", LocalDate.now());
                query.setParameter("id", sId);
                query.executeUpdate();
}

Exception:

2018-02-20 14:22:58.340 ERROR 424 --- [nio-8080-exec-9] o.a.e.impl.interceptor.CommandContext    : Error while closing command context


javax.persistence.TransactionRequiredException: Executing an update/delete query
at org.hibernate.jpa.spi.AbstractQueryImpl.executeUpdate(AbstractQueryImpl.java:54)
at wf.activiti.tools.ActivitiProcessEndListener.notify(ActivitiProcessEndListener.java:99)
at org.activiti.engine.impl.delegate.ExecutionListenerInvocation.invoke(ExecutionListenerInvocation.java:34)
at org.activiti.engine.impl.delegate.DelegateInvocation.proceed(DelegateInvocation.java:37)
at org.activiti.engine.impl.delegate.DefaultDelegateInterceptor.handleInvocation(DefaultDelegateInterceptor.java:25)
at org.activiti.engine.impl.bpmn.helper.ClassDelegate.notify(ClassDelegate.java:99)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:42)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:97)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:650)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:643)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityEnd.eventNotificationsCompleted(AtomicOperationActivityEnd.java:78)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:56)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:97)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:650)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:643)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:49)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:97)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:650)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:643)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.end(ExecutionEntity.java:406)
at org.activiti.engine.impl.bpmn.behavior.NoneEndEventActivityBehavior.execute(NoneEndEventActivityBehavior.java:24)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute.execute(AtomicOperationActivityExecute.java:60)
at org.activiti.engine.impl.interceptor.CommandContext.performOperation(CommandContext.java:97)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperationSync(ExecutionEntity.java:650)
at org.activiti.engine.impl.persistence.entity.ExecutionEntity.performOperation(ExecutionEntity.java:643)
at org.activiti.engine.impl.pvm.runtime.AtomicOperationTransitionNotifyListenerStart.eventNotificationsCompleted(AtomicOperationTransitionNotifyListenerStart.java:52)
at org.activiti.engine.impl.pvm.runtime.AbstractEventAtomicOperation.execute(AbstractEventAtomicOperation.java:56)
Abbas Kararawala
  • 1,254
  • 12
  • 19
L.E
  • 83
  • 1
  • 1
  • 7

1 Answers1

0

The StackOverflow error comes when the program runs indefinitely.

In your case, you implemented the event listener but did not specified as to which event it should listen. the class ActivitiEvent has a lot of implementations therefore executing your code every time any event is triggered, hence causing a stackoverflow error.

You should execute your logic when

<activiti:executionListener event="end" class="{your.class}"></activiti:executionListener>

Follow this example in userguide to implement your listener appropriately.

Abbas Kararawala
  • 1,254
  • 12
  • 19