AxonFramework / extension-mongo

Axon Framework extension for Mongo integration as a Dead Letter, Event, Saga and Tracking Token storage solution.
https://axoniq.io/
Apache License 2.0
25 stars 16 forks source link

Axon Framework 4.5.4 breaks the definition of a MongoSagaStore due to XStreamSerializer builder validation #136

Closed raphael-jungers closed 3 years ago

raphael-jungers commented 3 years ago

Basic information

Steps to reproduce

Using Spring Boot, declare a SagaStore Bean :

@Bean
fun mongoSagaStore(mongoClient: MongoClient, serializer: Serializer): SagaStore<Any> {  
    return MongoSagaStore.builder()  
        .serializer(serializer)  
        .mongoTemplate(DefaultMongoTemplate.builder().mongoDatabase(mongoClient).build())  
        .build()  
}

Expected behaviour

The application should start and Axon should use the provided Bean as SagaStore.

Actual behaviour

The application fails to start. I tracked the Exception and its cause.

I think the issue is with this line, which indeed does not provide a XStream instance to the XStreamSerializer builder.

Line 159 of MongoSagaStore.java file : private Serializer serializer = XStreamSerializer.builder().build();

I guess it could be solved easily by replacing this line by : private Serializer serializer = XStreamSerializer.builder().xStream(new XStream()).build();

I can help with a pull request if that is solving the issue.

Thank you

Full stacktrace

2021-10-09 15:02:19.556 ERROR 5741 --- [  restartedMain] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongoSagaStore' defined in class path resource [org/districted/commons/config/CommonMongoStoreConfig.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.axonframework.modelling.saga.repository.SagaStore]: Factory method 'mongoSagaStore' threw exception; nested exception is org.axonframework.common.AxonConfigurationException: The XStream instance is a hard requirement and should be provided
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918) ~[spring-context-5.3.10.jar:5.3.10]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583) ~[spring-context-5.3.10.jar:5.3.10]
    at org.springframework.boot.web.reactive.context.ReactiveWebServerApplicationContext.refresh(ReactiveWebServerApplicationContext.java:64) ~[spring-boot-2.5.5.jar:2.5.5]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-2.5.5.jar:2.5.5]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434) ~[spring-boot-2.5.5.jar:2.5.5]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:338) ~[spring-boot-2.5.5.jar:2.5.5]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343) ~[spring-boot-2.5.5.jar:2.5.5]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332) ~[spring-boot-2.5.5.jar:2.5.5]
    at org.districted.ServerApplicationKt.main(ServerApplication.kt:13) ~[main/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[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:566) ~[na:na]
    at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) ~[spring-boot-devtools-2.5.5.jar:2.5.5]
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.axonframework.modelling.saga.repository.SagaStore]: Factory method 'mongoSagaStore' threw exception; nested exception is org.axonframework.common.AxonConfigurationException: The XStream instance is a hard requirement and should be provided
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653) ~[spring-beans-5.3.10.jar:5.3.10]
    ... 24 common frames omitted
Caused by: org.axonframework.common.AxonConfigurationException: The XStream instance is a hard requirement and should be provided
    at org.axonframework.common.BuilderUtils.lambda$assertThat$0(BuilderUtils.java:48) ~[axon-messaging-4.5.4.jar:4.5.4]
    at org.axonframework.common.Assert.assertThat(Assert.java:115) ~[axon-messaging-4.5.4.jar:4.5.4]
    at org.axonframework.common.BuilderUtils.assertThat(BuilderUtils.java:48) ~[axon-messaging-4.5.4.jar:4.5.4]
    at org.axonframework.common.BuilderUtils.assertNonNull(BuilderUtils.java:62) ~[axon-messaging-4.5.4.jar:4.5.4]
    at org.axonframework.serialization.AbstractXStreamSerializer$Builder.validate(AbstractXStreamSerializer.java:390) ~[axon-messaging-4.5.4.jar:4.5.4]
    at org.axonframework.serialization.AbstractXStreamSerializer.<init>(AbstractXStreamSerializer.java:67) ~[axon-messaging-4.5.4.jar:4.5.4]
    at org.axonframework.serialization.xml.XStreamSerializer.<init>(XStreamSerializer.java:120) ~[axon-messaging-4.5.4.jar:4.5.4]
    at org.axonframework.serialization.xml.XStreamSerializer$Builder.build(XStreamSerializer.java:224) ~[axon-messaging-4.5.4.jar:4.5.4]
    at org.axonframework.extensions.mongo.eventhandling.saga.repository.MongoSagaStore$Builder.<init>(MongoSagaStore.java:159) ~[axon-mongo-4.4.jar:4.4]
    at org.axonframework.extensions.mongo.eventhandling.saga.repository.MongoSagaStore.builder(MongoSagaStore.java:72) ~[axon-mongo-4.4.jar:4.4]
    at org.districted.commons.config.CommonMongoStoreConfig.mongoSagaStore(CommonMongoStoreConfig.kt:30) ~[main/:na]
    at org.districted.commons.config.CommonMongoStoreConfig$$EnhancerBySpringCGLIB$$81189e95.CGLIB$mongoSagaStore$1(<generated>) ~[main/:na]
    at org.districted.commons.config.CommonMongoStoreConfig$$EnhancerBySpringCGLIB$$81189e95$$FastClassBySpringCGLIB$$b33dfb98.invoke(<generated>) ~[main/:na]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.3.10.jar:5.3.10]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:331) ~[spring-context-5.3.10.jar:5.3.10]
    at org.districted.commons.config.CommonMongoStoreConfig$$EnhancerBySpringCGLIB$$81189e95.mongoSagaStore(<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:62) ~[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:566) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.3.10.jar:5.3.10]
    ... 25 common frames omitted
smcvb commented 3 years ago

Thanks for providing the description here, @raphael-jungers.

I have already made the required adjustment in the MongoSagaStore. In issue #133, to be exact. The fact it isn't released yet is because other assignments are blocking the release right now.

The workaround to add a dedicated XStream instance, which you describe, is the recommended approach.

I would highly recommend anybody to provide a dedicated XStream instance if they're using the XStreamSerializer. Severals CVE's have come out for XStream that warrant this shift.

Concluding, the issue has already been resolved. As such, I will close this issue as a duplicate. Feel free to keep commenting if that's applicable.