Preferred Way to use Process Application Event Listener

Camunda Spring Boot Starter 2.0.0 introduced the @EnableProcessApplication annotation (#161) and made extending SpringBootProcessApplication superfluous.

But in my use case I would like to use the Process Application Event Listeners. Therefore I need to override the appropiate methods in SpringBootProcessApplication.

I now wonder what the preferred way of doing this is with 2.0.0?

To be honest I first got to know about the Process Application Event Listeners by reading the old Camunda Spring Boot Starter documentation. If the way to use it with 2.0.0 is to avoid the @EnableProcessApplication annotation it would be nice to have a documentation hint in the “Get Started” section.

Thanks for providing the starter :wink:

We use custom spring events for this. Have a look at https://github.com/camunda/camunda-bpm-spring-boot-starter/tree/2.0.0/extension/starter/src/main/java/org/camunda/bpm/spring/boot/starter/event

With spring > 4.2 (which is used in spring boot 1.4.2) you can than just let any bean listen to process application events via


@EventListener
public void engineStarted(ProcessApplicationStartedEvent unused) {
   // what you need to do
}

Hope that helps. I am currently writing the release blog post … since my view on the project is developer-biased, your feedback is highly appreciated. Please share your ideas how to improve the documentation.

1 Like

Hi Jan (@jangalinski) ,

thanks for your answer. In my case it is not about general Events but about the specific Camunda Process Application Event Listener. Actually it is about implementing ProcessApplicationInterface and overwriting the getExecutionListener and getTaskListener methods.

This was done so far by extending SpringBootProcessApplication which in the end extended AbstractProcessApplication (implementing the ProcessApplicationInterface). I find this very useful, e.g. in my camunda-variable-scope-demo example.

/**

  • The core Spring Application configuration.
    */
    @SpringBootApplication
    @ProcessApplication
    public class Main extends SpringBootProcessApplication {
@Override
public ExecutionListener getExecutionListener() {
    return new GlobalExecutionListener();
}
public static void main(final String... args) {
    SpringApplication.run(Main.class, args);
}

}

This does not work anymore if I replace the @ProcessApplication annotation with @EnableProcessApplication.

I guess in my case it makes sence to stay on the old style of configuration. I would appreciate if both “Get started” configurations would be mentioned in the documentation. And not only in the ReadMe file but also (or above all) in the documentation. Currently only links to some sample projects are mentioned here.

Thanks and keep up with the good work!

Franz

Hello Franz

ok, I see. I actually never used those global listeners and I must admit, I do not have a built in solution for the 2.0.0 starter right now.
You can of course fall back to the “extends” mechanism … but I could also think of implementing this for a 2.1 release … what do you think of using a Qualifier “processApplication” … if used on an Execution or Tasklistener, those get injected into the springBootProcessApplication and used like you do in your example …

Another option would be to actiate my camunda-bpm-reactor extension, you can subscribe listeners to events that are fired and control whether they are global, for all tasks, only for start events and so on.

If it is just a documentation issue, I would happily accept a pull request where you describe your use case. I personally wont be able to work on the extension til after the holidays.

regards
Jan

I opened an issue: https://github.com/camunda/camunda-bpm-spring-boot-starter/issues/184

Hi Jan,

thanks for the feedback. As I am not a very experienced Camunda user yet I do hard with advice. Using a Qualifier to make Execution or Tasklistener be injected to the SpringBootProcessApplication sounds great for me at the moment.

About the documentation: My current fear was to lose the description with the “extends” variant and thus also no longer be reminded of the possibilities which lie in it. If you enhance the project this might not be necessary any more. But I am not sure if there might be other “features” provided by the “extends” variant which are not covered by the @EnableProcessApplication" approach.

Documentation changes have to consider your enhancements. If there is something to do for 2.1, I will gladly help. No need to hurry at the moment as all functionality is provided (you just have to know how to do it ;-)).

Enjoy your holidays & kind regards
Franz

Hi, I see this issue is closed, but I don’t find how to get the the global Execution and TaskListener running while using camunda spring boot starter?

Additionally, all Release Notes 2.0.0 and above return HTTP-404 code.

I am trying to find a way how to get this running. Camunda Spring Engine says you’ll have to activate “Process Application Event Listener Plugin”, but was not able to find it in the starter.

Hi miwoe,

have a look at my example project here. In short I did it that way:

(1) Extend SpringBootProcessApplication and override getTaskListener

@SpringBootApplication
@ProcessApplication
public class Main extends SpringBootProcessApplication {

    @Override
    public TaskListener getTaskListener() {
        return new YourTaskListener();
    }

(2) Activate Event Listener Plugin

Activation of the Event Listener Plugin is just done by declaring a bean in your Spring Configuration

/**
 * Bean creation method for the Camunda ProcessApplicationEventListenerPlugin.
 * 
 * @return the ProcessApplicationEventListenerPlugin bean
 * @see <a href=
 *      "https://docs.camunda.org/manual/7.5/user-guide/process-applications/process-application-event-listeners/">Process
 *      Application Event Listeners</a>
 */
@Bean
ProcessApplicationEventListenerPlugin processApplicationEventListenerPlugin() {
    return new ProcessApplicationEventListenerPlugin();
}

My example uses Camunda Spring Boot Starter 1.3 but it also works with 2.0.0 in another project for me. Still seems to be supported in 2.2.0.

2 Likes

As you might have heard, the spring boot extension will be supported by camunda as of 7.8. While this is good news, currently, we are in a transition phase which may have lead to the missing docs/notes.

But I can confirm that the approach Frank introduced will still work.

Hi Jan,

not heard about that so far. Great news.
Thank you for bringing the module this far!

Kind regards,
Franz

You weren’t at the Community Day? Daniel Meyer announced this for 7.8 … note to self (and @DanielMeyer): we should really post that blog article!

1 Like

Hi @miwoe,
FYI I’ve just fixed release notes links in README . They should work now.

3 Likes

Hi @sdorokhova,
Just confirm with you guys, need I still use the way provided by @FrVaBe to register the global event listener for your Camunda Spring Boot 3.0?

Seems that somebody recommends to use Reactor plugin, please give me some advise.

My current customer asked about Event Listeners in Spring Boot as well, but I don’t see any improvement over what has been discussed here. Although the Issue has been closed it dosn’t seem to be solved.

Hi FrVaBe,

I am facing following exception while implementing processApplicationEventListener. Can you help on this Thanks :face_with_raised_eyebrow:
java.lang.NullPointerException: null
at org.camunda.bpm.spring.boot.starter.webapp.filter.LazyDelegateFilter.destroy(LazyDelegateFilter.java:49) ~[camunda-bpm-spring-boot-starter-webapp-core-2.3.0.jar:2.3.0]
at org.apache.catalina.core.ApplicationFilterConfig.release(ApplicationFilterConfig.java:318) ~[tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.StandardContext.filterStop(StandardContext.java:4623) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5421) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:226) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1435) [tomcat-embed-core-8.5.23.jar:8.5.23]
at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1424) [tomcat-embed-core-8.5.23.jar:8.5.23]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_131]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_131]
at java.lang.Thread.run(Thread.java:748) [na:1.8.0_131]

@Configuration
public class Config {

@Bean
ProcessApplicationEventListenerPlugin processApplicationEventListenerPlugin() {
	return new ProcessApplicationEventListenerPlugin();
}

}


@SpringBootApplication
@EnableProcessApplication
public class WebappExampleProcessApplication extends SpringBootProcessApplication {
public static void main(String… args) {
SpringApplication.run(WebappExampleProcessApplication.class, args);
}

@Override
public ExecutionListener getExecutionListener() {
	return new ExecutionListener() {
		
		public void notify(DelegateExecution execution) throws Exception {
			System.out.println("%%%%%%%%%%%%%%%%%%%%%%%%%%");
			
		}
	};
}

}

org.camunda.bpm.springboot camunda-bpm-spring-boot-starter-webapp 2.3.0 com.h2database h2

I have tried all the various methods described here to register a global execution and task listener. Can someone tell me the correct syntax to use for: Spring Boot 2.2, Camunda 7.12, using camunda-bpm-spring-boot-starter (rest and webapp)

@SpringBootApplication
@ProcessApplication
public class myApplication extends SpringBootProcessApplication implements ProcessApplicationInterface {
    @Override
    public TaskListener getTaskListener() {
        return new TaskListener() {
        	final Logger log = LoggerFactory.getLogger(this.getClass());
        	public void notify(DelegateTask delegateTask) {
        	    log.info("BPMNTaskListener '{}' ", delegateTask);
        	}
        };
    }
    @Override
    public ExecutionListener getExecutionListener() {
    	return new ExecutionListener() {
    		final Logger log = LoggerFactory.getLogger(this.getClass());
    		public void notify(DelegateExecution execution) throws Exception {
    			log.info("BPMNExecutionListener '{}' ", execution);
    			
    		}
    	};
    }
    
    @Bean
    ProcessApplicationEventListenerPlugin processApplicationEventListenerPlugin() {
        return new ProcessApplicationEventListenerPlugin();
    }
.....
}

My getTaskListener and getExecutionListener are never called.

Hello @tmartin,
I’m facing the same issue, except I’m extending SpringServletProcessApplication.
Did you managed to find a solution to it?

Sadly I had to implement my own parser listeners that hook into the reading of the BPMN XML at the construction of the model in memory to add my listeners. It is a little more work but not too bad

public class UserTaskParseListenerPlugin extends AbstractProcessEnginePlugin {

@Override
public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
	List<BpmnParseListener> preParseListeners = processEngineConfiguration.getCustomPreBPMNParseListeners();
	if (preParseListeners == null) {
		preParseListeners = new ArrayList<BpmnParseListener>();
		processEngineConfiguration.setCustomPreBPMNParseListeners(preParseListeners);
	}
	preParseListeners.add(new UserTaskParseListener());
}

}

public class ProgressLoggingSupportParseListenerPlugin extends AbstractProcessEnginePlugin {

@Override
public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {

	// get all existing preParseListeners
	List<BpmnParseListener> preParseListeners = processEngineConfiguration.getPreParseListeners();

	if (preParseListeners == null) {

		// if no preParseListener exists, create new list
		preParseListeners = new ArrayList<BpmnParseListener>();
		processEngineConfiguration.setPreParseListeners(preParseListeners);
	}

	// add new BPMN Parse Listener
	preParseListeners.add(new ProgressLoggingSupportParseListener());
}

}

I used https://github.com/camunda/camunda-bpm-reactor as a reference in my development