cancel
Showing results for 
Search instead for 
Did you mean: 

Execution of listeners does not capture values

alexsimas
Champ on-the-rise
Champ on-the-rise
Hello peoples!

I've been trying for a few days to run listeners in a process with no success. I've done enough research and nothing.

See my code below:

package br.simas.process.listener;

import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

public class MyExecutionListener implements ExecutionListener {
   
   private static final long serialVersionUID = 1L;

   @Override
   public void notify(DelegateExecution execution) throws Exception {
      // TODO Auto-generated method stub

      try {

         execution.setVariable("initiator", execution.getEngineServices()
               .getHistoryService()
               .createNativeHistoricProcessInstanceQuery().singleResult()
               .getStartUserId());

               // debug information
         System.out.println("Id corrente: "
               + execution.getCurrentActivityId());
         System.out.println("A definição do processo é: "
               + execution.getProcessDefinitionId());
         System.out.println(" O id da instância é: "
               + execution.getProcessInstanceId());

      } catch (NullPointerException e) {
         System.out.println(" O problema é " + e.getMessage());
      }
   }
}

The problem is that it always returns NULL.

I'm new to Activiti and I'm still studying a lot, what I want is to just capture the user who started the process instance, write that value to a variable and then use listener tasks to do the assignment capturing this variable, both for itself and for Your immediate superior through a SQL query.

If you have a simpler way to capture this variable would be interesting.

Can someone help me?
1 ACCEPTED ANSWER

alexsimas
Champ on-the-rise
Champ on-the-rise
Hello Roxannas, thank you!

It helped me a lot, so much so that by researching the interfaces in javadoc and from the ExecutionContext class, which you showed me, I was able to solve my problem and retrieve the variables I wanted.

I have the pom.xml configured correctly to bring the dependencies of activiti-engine-5.22.0 and other dependencies but I did not find the UserService interface nor in the documentation. I'll search better because it seems like a great interface.

There is time that I do not develop and I came back only because I fell in love with BPM, I still need some months of readaptation to understand the sophistication of its code, I am already diving in the Spring to facilitate my life.

Here's how I solved the problem:

1: Retrieving and defining the variable of who initiated the process:

<java>

public class MyExecutionListener implements ExecutionListener {

private static final long serialVersionUID = 1L;

@Override
public void notify(DelegateExecution execution) throws Exception {
  // TODO Auto-generated method stub

  try {

   ExecutionContext executionContext = Context.getExecutionContext();

   List<IdentityLinkEntity> identityLinkEntity = executionContext
     .getProcessInstance().getIdentityLinks();

   System.out
     .println("*************** the Start Listener is called **************");

   String userID = null;

   for (IdentityLinkEntity identityLinkEntityList : identityLinkEntity) {

    if (userID == null) {
     userID = identityLinkEntityList.getUserId();
     execution.setVariable("userInitiatorName", userID);
     break;
    }
   }

  } catch (Exception e) {
   System.out.println(e.getMessage());
  }
}
}
</java>

2: Assigning the User Task

<java>

public class MytaskListener implements TaskListener {

private static final long serialVersionUID = 1L;

@Override
public void notify(DelegateTask task) {
  // TODO Auto-generated method stub

  try {

   task.setAssignee((String) task.getVariable("userInitiatorName"));
   System.out.println("Variavel capturada é: "
     + task.getVariable("userInitiatorName"));
  } catch (Exception e) {
   System.out.println(e.getMessage());
  }

}

}
</java>

Thanks,

Alex Simas

View answer in original post

4 REPLIES 4

roxanaspatariu
Champ in-the-making
Champ in-the-making
The following class should be defined in a package called "com.activiti.extension.bean", under your java folder.

@Component("Assignment")
public class Assignment implements ExecutionListener{

@Autowired
protected UserService activitiUserService;

public void notify(DelegateExecution delegateExecution) {

ProcessEngineConfiguration processEngineConfiguration = Context.getProcessEngineConfiguration();
BpmnModel bpmnModel = processEngineConfiguration.getRepositoryService().getBpmnModel(delegateExecution.getProcessDefinitionId());
String currentActivityId = delegateExecution.getCurrentActivityId();
FlowElement currentFlowElement = bpmnModel.getFlowElement(currentActivityId);

String initiatorId = null;
User initiatorUser = null;
User managerUser = null;
if (currentFlowElement != null) {
   if(currentFlowElement instanceof SequenceFlow){
   initiatorId = (String) delegateExecution.getVariable("initiator");
   initiatorUser = activitiUserService.findUser(Long.parseLong(initiatorId));
   managerUser = activitiUserService.findUser(initiatorUser.getManagerUserId());
   }else if (currentFlowElement instanceof UserTask && initiatorUser != null && managerUser != null) {
   UserTask userTask = (UserTask) currentFlowElement;
   userTask.setAssignee(String.valueOf(initiatorUser.getId()));
   userTask.setAssignee(String.valueOf(managerUser.getId()))
   }
}
}
}



You should specify this execution listener on the sequence flow element previous to your user task, by adding in the execution listener pop-up, the component name in the delegate expression section as ${Assignment} and also select the event "take". And in your user task you should do the same thing, but change the event as "start".

alexsimas
Champ on-the-rise
Champ on-the-rise
Thank you Roxanas!

I think I'm beginning to understand how this works. Instead of classes I will use delegate expression.

I confess that I am facing certain difficulties in understanding the workings of Listeners, I have read the books activi in action and the most practical and very good Activiti 5x Business Process Management, but I find them poor in the approach of Listeners for beginner users.

Your tip was precious, I'm studying the class that sent me doing a parallel with the documentation, but I need more clarification.

Eclipse can not find the UserService class and I also did not find the package com.activiti.extension.bean.

Could you guide me how to solve this problem? If you have any practical study references on Listeners to share, I would appreciate it.

Thank you very much in advance!

Alex Simas

roxanaspatariu
Champ in-the-making
Champ in-the-making
You're welcome! I'm glad my answer gave you some clarity.

In the same project in which you have Activiti, you have to create your own module, and in the pom.xml file there has to be specified the dependency for activity-engine module.
That brings you the jars you need in your module and you will have access to the Activiti classes you need (UserService, and others you lack). In the java folder, create a package named  "com.activiti.extension.bean", in which you define your listeners. There is a configuration class in Activiti that scans this package and will know how to treat your classes.  

alexsimas
Champ on-the-rise
Champ on-the-rise
Hello Roxannas, thank you!

It helped me a lot, so much so that by researching the interfaces in javadoc and from the ExecutionContext class, which you showed me, I was able to solve my problem and retrieve the variables I wanted.

I have the pom.xml configured correctly to bring the dependencies of activiti-engine-5.22.0 and other dependencies but I did not find the UserService interface nor in the documentation. I'll search better because it seems like a great interface.

There is time that I do not develop and I came back only because I fell in love with BPM, I still need some months of readaptation to understand the sophistication of its code, I am already diving in the Spring to facilitate my life.

Here's how I solved the problem:

1: Retrieving and defining the variable of who initiated the process:

<java>

public class MyExecutionListener implements ExecutionListener {

private static final long serialVersionUID = 1L;

@Override
public void notify(DelegateExecution execution) throws Exception {
  // TODO Auto-generated method stub

  try {

   ExecutionContext executionContext = Context.getExecutionContext();

   List<IdentityLinkEntity> identityLinkEntity = executionContext
     .getProcessInstance().getIdentityLinks();

   System.out
     .println("*************** the Start Listener is called **************");

   String userID = null;

   for (IdentityLinkEntity identityLinkEntityList : identityLinkEntity) {

    if (userID == null) {
     userID = identityLinkEntityList.getUserId();
     execution.setVariable("userInitiatorName", userID);
     break;
    }
   }

  } catch (Exception e) {
   System.out.println(e.getMessage());
  }
}
}
</java>

2: Assigning the User Task

<java>

public class MytaskListener implements TaskListener {

private static final long serialVersionUID = 1L;

@Override
public void notify(DelegateTask task) {
  // TODO Auto-generated method stub

  try {

   task.setAssignee((String) task.getVariable("userInitiatorName"));
   System.out.println("Variavel capturada é: "
     + task.getVariable("userInitiatorName"));
  } catch (Exception e) {
   System.out.println(e.getMessage());
  }

}

}
</java>

Thanks,

Alex Simas