Axon and hierarchical Spring Application Context

Hi everyone,

we develop a Spring Boot application and heavily rely on hierarchical Spring application contexts to separate the modules. Therefore we have to disable Spring’s AutoConfiguration. The concept is described in this blog: https://www.blackpepper.co.uk/blog/a-modular-architecture-with-spring-boot

In this application we would like to use Axon. We decided to have a dedicated child application context for Axon (with JPA Event Store) and export some beans (e.g. commandGateway) to the root context. This enables all child contexts to access these beans. Unfortunately we have a problem while trying to register our handlers (command, events, queries). For example we want the command handlers to be subscribed to the commandBus. How can we achieve this? Can we just import some Axon (Spring) configurations in the module which contains the CommandHandler? I just don’t understand what all the different configurations do and if there is a dedicated configuration which scans for @CommandHandler and registers it at the CommandBus.

Thanks for help!

Kind regards
Oliver Libutzki

As executable code says more than thousand words, I added an example at GitHub: https://github.com/OLibutzki/axon-hierarchical.

An exception is thrown when starting the application:

`

org.axonframework.common.AxonConfigurationException: Missing EventProcessingConfiguration bean
at org.axonframework.spring.config.SpringAxonAutoConfigurer.lambda$registerBeanDefinitions$35(SpringAxonAutoConfigurer.java:206) ~[axon-spring-4.1.1.jar:4.1.1]
at java.base/java.util.Optional.orElseThrow(Optional.java:408) ~[na:na]
at org.axonframework.spring.config.SpringAxonAutoConfigurer.registerBeanDefinitions(SpringAxonAutoConfigurer.java:206) ~[axon-spring-4.1.1.jar:4.1.1]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromRegistrars$1(ConfigurationClassBeanDefinitionReader.java:364) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at java.base/java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:na]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:363) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:145) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:327) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:232) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:275) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:95) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:705) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:531) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at org.springframework.boot.builder.SpringApplicationBuilder.run(SpringApplicationBuilder.java:139) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE]
at de.libutzki.axon.axonhierarchical.AxonHierarchicalApplication.main(AxonHierarchicalApplication.java:19) ~[classes/:na]

`

I added some more explanation in the README.MD of the repo: https://github.com/OLibutzki/axon-hierarchical

After some further investigation I decided to create a GitHub issue: https://github.com/AxonFramework/AxonFramework/issues/1055

Hi all,

Just per reference for an encounter of this thread, Oliver has provided the issue #1055, but more so also an implementation of the problem!
It will be part of Axon Framework release 4.2, which should be relesaed shortly.

Ow, and Oliver, thanks so much for the contribution!

Cheers,
Steven