Search code examples
mongodbspring-bootcqrsevent-sourcingaxon

Spring Boot with mongo from axonIQ 3 to 4


So I was trying to move my module from using axonIQ 3.4 to 4.1, I'm using a mongodb to save the events rather than the axon server.

In axon 3 you don't need to use the axon server whereas in the 4 release it will be the default unless you exclude it EXPLICITLY in your pom/build.gradle

compile('org.axonframework:axon-spring-boot-starter:4.1') {
    exclude group: 'org.axonframework', module: 'axon-server-connector'
}

I moved to the new mongo extensions as well as the old lib was deprecated

compile group: 'org.axonframework.extensions.mongo', name: 'axon-mongo', version: '4.1'

I'm also using the following code (as mentioned in their tutorials) to store the events

@Bean
public EventStorageEngine storageEngine(MongoClient client) {
    return MongoEventStorageEngine.builder().mongoTemplate(DefaultMongoTemplate.builder().mongoDatabase(client).build()).build();
}

I'm getting the following error when I try to run the application (even before trying to run any event)

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy at sun.reflect.annotation.AnnotationParser.parseClassArray(AnnotationParser.java:724) ~[na:1.8.0_141] at sun.reflect.annotation.AnnotationParser.parseArray(AnnotationParser.java:531) ~[na:1.8.0_141] at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:355) ~[na:1.8.0_141] at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:286) ~[na:1.8.0_141] at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:120) ~[na:1.8.0_141] at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:72) ~[na:1.8.0_141] at java.lang.reflect.Executable.declaredAnnotations(Executable.java:599) ~[na:1.8.0_141] at java.lang.reflect.Executable.declaredAnnotations(Executable.java:597) ~[na:1.8.0_141] at java.lang.reflect.Executable.getDeclaredAnnotations(Executable.java:588) ~[na:1.8.0_141] at java.lang.reflect.Method.getDeclaredAnnotations(Method.java:630) ~[na:1.8.0_141] at java.lang.reflect.AccessibleObject.getAnnotations(AccessibleObject.java:207) ~[na:1.8.0_141] at org.axonframework.common.annotation.AnnotationUtils.getAnnotation(AnnotationUtils.java:130) ~[axon-messaging-4.1.jar:4.1] at org.axonframework.common.annotation.AnnotationUtils.findAnnotationAttributes(AnnotationUtils.java:76) ~[axon-messaging-4.1.jar:4.1] at org.axonframework.common.annotation.AnnotationUtils.findAnnotationAttributes(AnnotationUtils.java:110) ~[axon-messaging-4.1.jar:4.1] at org.axonframework.spring.config.SpringAxonAutoConfigurer.lambda$null$40(SpringAxonAutoConfigurer.java:255) ~[axon-spring-4.1.jar:4.1] at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_141] at java.util.LinkedList$LLSpliterator.tryAdvance(LinkedList.java:1249) ~[na:1.8.0_141] at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126) ~[na:1.8.0_141] at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498) ~[na:1.8.0_141] at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485) ~[na:1.8.0_141] at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_141] at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230) ~[na:1.8.0_141] at java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196) ~[na:1.8.0_141] at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_141] at java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:449) ~[na:1.8.0_141] at org.axonframework.spring.config.SpringAxonAutoConfigurer.lambda$registerEventHandlerRegistrar$42(SpringAxonAutoConfigurer.java:257) ~[axon-spring-4.1.jar:4.1] at java.util.Iterator.forEachRemaining(Iterator.java:116) ~[na:1.8.0_141] at org.axonframework.spring.config.SpringAxonAutoConfigurer.registerEventHandlerRegistrar(SpringAxonAutoConfigurer.java:248) ~[axon-spring-4.1.jar:4.1] at org.axonframework.spring.config.SpringAxonAutoConfigurer.registerBeanDefinitions(SpringAxonAutoConfigurer.java:214) ~[axon-spring-4.1.jar:4.1] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.lambda$loadBeanDefinitionsFromRegistrars$1(ConfigurationClassBeanDefinitionReader.java:358) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at java.util.LinkedHashMap.forEach(LinkedHashMap.java:684) ~[na:1.8.0_141] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsFromRegistrars(ConfigurationClassBeanDefinitionReader.java:357) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:145) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:117) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:328) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:233) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:273) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:93) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:694) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:532) ~[spring-context-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:140) ~[spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:759) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:395) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:327) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1255) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1243) [spring-boot-2.0.3.RELEASE.jar:2.0.3.RELEASE] at com.murex.quality.gate.QGApplication.main(QGApplication.java:16) [classes/:na]

If I roll back to axonIQ 3.4 everything works properly but can't get it to work with 4.1


Solution

  • The exception you're getting is, I think, by no means tied to the fact you have MongoDb instead of Axon Server as the means to store events and route all your messages in a distributed matter automatically.

    The exception points to the AnnotationUtils, a utilities class Axon uses to check for the Axon specific annotation on the components you provide. More specifically, it fails on a check in the SpringAxonAutoConfigurer when it tries to find the MessageHandler annotation.

    Every message handling annotation, albeit Command, Event, Saga Event, Query, whatever, extends from this type, which your set up is unable to find for some reason.

    What however did happen with the Axon Framework when the move from version 3.x to 4.x was made, is that the package hierarchy was changed. The MessageHandler handler annotation moved from package org.axonframework.messaging.annotation in the axon-core module in Axon 3.x to the org.axonframework.messaging package in the axon-messaging module in Axon 4.x.

    Would you mind trying out 4.1 again, but emptying any cache you might have with dependencies first, to ensure you do not have both Axon 3.x and 4.1 present?

    Hope this helps! If not, we need to look a little further.