question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Axon Spring Boot application fails to start when multiple EventUpcasterChain spring beans are defined

See original GitHub issue

Basic information

  • Axon Framework version: 4.6.1
  • JDK version: 17
  • Complete executable reproducer if available (e.g. GitHub Repo): See attached project zip.

Steps to reproduce

Unzip the attached project and run: ./gradlew bootRun

Expected behaviour

The application is expected to start successfully.

Actual behaviour

The application fails to startup throwing this exception:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'eventStorageEngine' defined in class path resource [upcasterchaintest/AxonConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.axonframework.eventsourcing.eventstore.EventStorageEngine]: Factory method 'eventStorageEngine' threw exception; nested exception is org.axonframework.common.AxonConfigurationException: Expected single candidate for component [EventUpcasterChain]. Found candidates: [eventUpcasterChain1, eventUpcasterChain2]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:955) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.23.jar:5.3.23]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.23.jar:5.3.23]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147) ~[spring-boot-2.7.4.jar:2.7.4]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734) ~[spring-boot-2.7.4.jar:2.7.4]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408) ~[spring-boot-2.7.4.jar:2.7.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) ~[spring-boot-2.7.4.jar:2.7.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306) ~[spring-boot-2.7.4.jar:2.7.4]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295) ~[spring-boot-2.7.4.jar:2.7.4]
        at upcasterchaintest.ApplicationKt.main(Application.kt:14) ~[main/:na]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.axonframework.eventsourcing.eventstore.EventStorageEngine]: Factory method 'eventStorageEngine' threw exception; nested exception is org.axonframework.common.AxonConfigurationException: Expected single candidate for component [EventUpcasterChain]. Found candidates: [eventUpcasterChain1, eventUpcasterChain2]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.23.jar:5.3.23]
        at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.23.jar:5.3.23]
        ... 19 common frames omitted
Caused by: org.axonframework.common.AxonConfigurationException: Expected single candidate for component [EventUpcasterChain]. Found candidates: [eventUpcasterChain1, eventUpcasterChain2]
        at org.axonframework.spring.config.SpringConfigurer$ComponentLocator.findBean(SpringConfigurer.java:71) ~[axon-spring-4.6.1.jar:4.6.1]
        at org.axonframework.spring.config.SpringConfigurer.defaultComponent(SpringConfigurer.java:50) ~[axon-spring-4.6.1.jar:4.6.1]
        at org.axonframework.config.DefaultConfigurer.defaultUpcasterChain(DefaultConfigurer.java:523) ~[axon-configuration-4.6.1.jar:4.6.1]
        at org.axonframework.config.Component.get(Component.java:85) ~[axon-configuration-4.6.1.jar:4.6.1]
        at org.axonframework.config.DefaultConfigurer$ConfigurationImpl.upcasterChain(DefaultConfigurer.java:1021) ~[axon-configuration-4.6.1.jar:4.6.1]
        at upcasterchaintest.AxonConfig.eventStorageEngine(AxonConfig.kt:29) ~[main/:na]
        at upcasterchaintest.AxonConfig$$EnhancerBySpringCGLIB$$67064d7b.CGLIB$eventStorageEngine$0(<generated>) ~[main/:na]
        at upcasterchaintest.AxonConfig$$EnhancerBySpringCGLIB$$67064d7b$$FastClassBySpringCGLIB$$d63c1be1.invoke(<generated>) ~[main/:na]
        at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.23.jar:5.3.23]
        at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.23.jar:5.3.23]
        at upcasterchaintest.AxonConfig$$EnhancerBySpringCGLIB$$67064d7b.eventStorageEngine(<generated>) ~[main/:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
        at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
        at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.23.jar:5.3.23]
        ... 20 common frames omitted

However when removing 1 of the EventUpcasterChain beans defined in src/main/kotlin/upcasterchaintest/Upcasters.kt the application will start successfully.

upcasterchaintest.zip

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:8 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
marnixrennecommented, Oct 20, 2022

@smcvb Yes, I can confirm that all UpcasterChains were invoked during upcasting.

1reaction
marnixrennecommented, Oct 18, 2022

@smcvb yes, this setup used to work prior to using the new Configuration API (instead, using the deprecated AxonConfiguration class). Currently we group our EventUpcasters per event type in an EventUpcasterChain and only these EventUpcasterChains are spring beans. From what I understand from the documentation this is a legitimate way to use Axon framework.

What I noticed when digging through the upcasterChain() call in the DefaultConfiguration class was that it was expecting a single bean of type EventUpcasterChain defined in the spring application context which was of course not the case.

For now we found a workaround by not using the Axon maven BOM, but explicitly specifying the versions in the dependencies. This probably changes the order in which spring components are loaded and works for us by coincidence, but this will not fix the example project included with this issue. So I still think it’s a bug, or subclassing EventUpcasterChain should be prohibited.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Axon Framework - Release 4.6.2 - Announcements
... Axon Spring Boot application fails to start when multiple EventUpcasterChain spring beans are defined #2445; Added Spring Resource ...
Read more >
Error creating bean with name 'commandGateway' defined in ...
Error creating bean with name 'commandGateway' defined in class path resource [org/axonframework/springboot/autoconfig/AxonAutoConfiguration.
Read more >
Releases · AxonFramework/AxonFramework - GitHub
... Axon Spring Boot application fails to start when multiple EventUpcasterChain spring beans are defined #2445; Added Spring Resource Injector to ...
Read more >
axon 3.1.1 - upcasting in spring boot - how to register
I need to upcast a PlayerCreated event in my spring boot axon application. ... I am using the axon-spring-boot-starter, so I do not...
Read more >
Smooth implementation of CQRS/ES with Spring Boot and ...
In the last article, I described what CQRS and Event Sourcing are and what problems they solve. You can find there all the...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found