cancel
Showing results for 
Search instead for 
Did you mean: 

Activiti 6: Inject custom TaskListener programmatically

dennie_oberlatz
Champ in-the-making
Champ in-the-making
Hi,

I am currently migrating from activiti 5.20.0 to 6.0.0.Beta2. The project is a spring boot (version: 1.3.5.RELEASE) project with activiti integration.

My goal is to inject a custom task listener via Java. I am facing a problem with my current approach due to an API change in activiti 6.

How I have solved the problem so far:
In activiti 5 a custom task listener is injected by overriding the method DefaultActivityBehaviorFactory::createUserTaskActivityBehavior(UserTask userTask, TaskDefinition taskDefinition) and setting the custom listener to the taskDefinition. The custom DefaultActivityBehaviorFactory replaces the original one in the SpringProcessEngineConfiguration.

Custom DefaultActivityBehaviorFactory:
[java]
@Named
public class MyActivityBehaviorFactory extends DefaultActivityBehaviorFactory {

    @Inject
    TaskListener userTaskCreatedListener;

    @Override
    public UserTaskActivityBehavior createUserTaskActivityBehavior(UserTask userTask, TaskDefinition taskDefinition) {
        taskDefinition.addTaskListener(TaskListener.EVENTNAME_CREATE, userTaskCreatedListener);
        return super.createUserTaskActivityBehavior(userTask, taskDefinition);
    }
}
[/java]

Register custom DefaultActivityBehaviorFactory:
[java]
@Configuration
public class ActivitiConfiguration {

    @Inject
    MyActivityBehaviorFactory myActivityBehaviorFactory;

    @Bean
    public BeanPostProcessor activitiConfigurer() {
        return new BeanPostProcessor() {

            @Override
            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
                // inject custom behavior into the activiti process engine
                // configuration
                if (bean instanceof SpringProcessEngineConfiguration) {
                    ((SpringProcessEngineConfiguration) bean).setActivityBehaviorFactory(myActivityBehaviorFactory);
                }
                return bean;
            }
        };
    }
}
[/java]

In activiti 6 that does not work anymore because the method DefaultActivityBehaviorFactory::createUserTaskActivityBehavior(ExpressionManager expressionManager, UserTask userTask) does not provide the taskDefinition anymore.

A link to a migration guide from activiti 5 to 6 or a hint on how to solve my problem would be appreciated.
Best regards,
Dennie
3 REPLIES 3

dennie_oberlatz
Champ in-the-making
Champ in-the-making
I have found a solution based on how it is done in activiti-crystalball:

Custom UserTaskParseHandler:
[java]
public class AddListenerUserTaskParseHandler extends UserTaskParseHandler {

    private final String eventName;
    private final TaskListener taskListener;

    public AddListenerUserTaskParseHandler(String eventName, TaskListener taskListener) {
        this.eventName = eventName;
        this.taskListener = taskListener;
    }

    @Override
    protected void executeParse(BpmnParse bpmnParse, UserTask userTask) {
        super.executeParse(bpmnParse, userTask);

        ActivitiListener listener = new ActivitiListener();
        listener.setEvent(eventName);
        listener.setImplementationType(ImplementationType.IMPLEMENTATION_TYPE_INSTANCE);
        listener.setInstance(taskListener);
        userTask.getTaskListeners().add(listener);

    }
}
[/java]

Register custom listener:
[java]
@Configuration
public class ActivitiConfiguration {

    @Inject
    UserTaskCreatedListener userTaskCreatedListener;

    @Bean
    public BeanPostProcessor activitiConfigurer() {
        return new BeanPostProcessor() {

            @Override
            public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
                // inject custom listener into the activiti process engine
                // configuration
                if (bean instanceof SpringProcessEngineConfiguration) {
                    ((SpringProcessEngineConfiguration) bean).setCustomDefaultBpmnParseHandlers(Arrays.asList(
                            new AddListenerUserTaskParseHandler(TaskListener.EVENTNAME_CREATE, userTaskCreatedListener)));
                }
                return bean;
            }
        };
    }
}
[/java]

I have still the following questions:
1. Adding the task listener to the user task could have been done also in the overridden DefaultActivityBehaviorFactory as I did originally. Could anybody explain to me if this would have made a difference?
2. Is my approach a proper solution to add custom a-user-task-has-been-created behavior or can that be achieved in a better way? A requirement is to not do that throught the BPMN xml definition.

Best,
Dennie

jbarrez
Star Contributor
Star Contributor
1. No, wouldn't be a difference. it's a matter of style/taste

2. yes it is. It is exactly the kind of use case the ParseHandler was created for.

dennie_oberlatz
Champ in-the-making
Champ in-the-making
Hi Joram,

thanks a lot for your answer!

Dennie