We have encountered an issue while upgrading our application, which is built with Spring Boot and Axon Framework, from Java 11 and Spring Boot 2.7 to Java 17 and Spring Boot 3. We’re using Axon v4.9.1. We use PostgreSQL as an event store. The problem revolves around a regression in XStream serialization, leading to the following error:
2024-02-05T10:40:47.708Z ERROR 1 --- [integration-service] [nio-8080-exec-2] o.a.c.c.C.[.[.[.[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [/integration] threw exception [Request processing failed: org.axonframework.eventsourcing.eventstore.EventStoreException: Cannot reuse aggregate identifier [c8085e30-00d7-416d-a466-37727dd7c9e6] to create aggregate [JobAggregate] since identifiers need to be unique.] with root cause
2024-02-05T10:40:47.712386774Z
2024-02-05T10:40:47.712442504Z com.thoughtworks.xstream.converters.ConversionException: No converter available
2024-02-05T10:40:47.712454621Z ---- Debugging information ----
2024-02-05T10:40:47.712463905Z message : No converter available
2024-02-05T10:40:47.712476905Z type : java.util.Collections$EmptyList
2024-02-05T10:40:47.712486447Z converter : com.thoughtworks.xstream.converters.reflection.ReflectionConverter
2024-02-05T10:40:47.712496123Z message[1] : Unable to make field protected transient int java.util.AbstractList.modCount accessible: module java.base does not "opens java.util" to unnamed module @11b03c1f
2024-02-05T10:40:47.712505918Z -------------------------------
2024-02-05T10:40:47.712514264Z at com.thoughtworks.xstream.core.DefaultConverterLookup.lookupConverterForType(DefaultConverterLookup.java:88) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712525184Z at com.thoughtworks.xstream.XStream$1.lookupConverterForType(XStream.java:478) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712527769Z at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:49) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712530528Z at com.thoughtworks.xstream.core.AbstractReferenceMarshaller$1.convertAnother(AbstractReferenceMarshaller.java:83) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712537666Z at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshallField(AbstractReflectionConverter.java:270) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712540436Z at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter$2.writeField(AbstractReflectionConverter.java:174) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712543070Z at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.doMarshal(AbstractReflectionConverter.java:262) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712546915Z at com.thoughtworks.xstream.converters.reflection.AbstractReflectionConverter.marshal(AbstractReflectionConverter.java:90) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712549750Z at com.thoughtworks.xstream.core.AbstractReferenceMarshaller.convert(AbstractReferenceMarshaller.java:68) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712552357Z at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:59) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712554926Z at com.thoughtworks.xstream.core.TreeMarshaller.convertAnother(TreeMarshaller.java:44) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712557543Z at com.thoughtworks.xstream.core.TreeMarshaller.start(TreeMarshaller.java:83) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712560067Z at com.thoughtworks.xstream.core.AbstractTreeMarshallingStrategy.marshal(AbstractTreeMarshallingStrategy.java:37) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712562690Z at com.thoughtworks.xstream.XStream.marshal(XStream.java:1303) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712570230Z at com.thoughtworks.xstream.XStream.marshal(XStream.java:1292) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712574376Z at com.thoughtworks.xstream.XStream.toXML(XStream.java:1265) ~[xstream-1.4.20.jar:1.4.20]
2024-02-05T10:40:47.712578234Z at org.axonframework.serialization.xml.XStreamSerializer.doSerialize(XStreamSerializer.java:132) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712582040Z at org.axonframework.serialization.AbstractXStreamSerializer.serialize(AbstractXStreamSerializer.java:110) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712585954Z at org.axonframework.serialization.SerializedObjectHolder.serializePayload(SerializedObjectHolder.java:57) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712590101Z at org.axonframework.messaging.GenericMessage.serializePayload(GenericMessage.java:167) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712597110Z at org.axonframework.messaging.MessageDecorator.serializePayload(MessageDecorator.java:66) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712601455Z at org.axonframework.eventhandling.AbstractEventEntry.<init>(AbstractEventEntry.java:84) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712604739Z at org.axonframework.eventhandling.AbstractDomainEventEntry.<init>(AbstractDomainEventEntry.java:55) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712607868Z at org.axonframework.eventhandling.AbstractSequencedDomainEventEntry.<init>(AbstractSequencedDomainEventEntry.java:54) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712610721Z at org.axonframework.eventsourcing.eventstore.jpa.DomainEventEntry.<init>(DomainEventEntry.java:49) ~[axon-eventsourcing-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712613417Z at org.axonframework.eventsourcing.eventstore.jpa.JpaEventStorageEngine.createEventEntity(JpaEventStorageEngine.java:427) ~[axon-eventsourcing-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712616035Z at org.axonframework.eventsourcing.eventstore.jpa.JpaEventStorageEngine.lambda$null$5(JpaEventStorageEngine.java:320) ~[axon-eventsourcing-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712618766Z at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197) ~[na:na]
2024-02-05T10:40:47.712621338Z at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
2024-02-05T10:40:47.712623866Z at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
2024-02-05T10:40:47.712626394Z at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
2024-02-05T10:40:47.712628917Z at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150) ~[na:na]
2024-02-05T10:40:47.712631445Z at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173) ~[na:na]
2024-02-05T10:40:47.712634005Z at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
2024-02-05T10:40:47.712636536Z at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596) ~[na:na]
2024-02-05T10:40:47.712641355Z at org.axonframework.eventsourcing.eventstore.jpa.JpaEventStorageEngine.lambda$appendEvents$6(JpaEventStorageEngine.java:320) ~[axon-eventsourcing-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712644084Z at org.axonframework.common.transaction.TransactionManager.executeInTransaction(TransactionManager.java:47) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712646715Z at org.axonframework.eventsourcing.eventstore.jpa.JpaEventStorageEngine.appendEvents(JpaEventStorageEngine.java:318) ~[axon-eventsourcing-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712649367Z at org.axonframework.eventsourcing.eventstore.AbstractEventStorageEngine.appendEvents(AbstractEventStorageEngine.java:105) ~[axon-eventsourcing-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712652004Z at org.axonframework.eventsourcing.eventstore.AbstractEventStore.prepareCommit(AbstractEventStore.java:66) ~[axon-eventsourcing-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712654891Z at org.axonframework.eventhandling.AbstractEventBus.doWithEvents(AbstractEventBus.java:256) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712657562Z at org.axonframework.eventhandling.AbstractEventBus.lambda$null$11(AbstractEventBus.java:170) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712660135Z at org.axonframework.messaging.unitofwork.MessageProcessingContext.notifyHandlers(MessageProcessingContext.java:72) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712664025Z at org.axonframework.messaging.unitofwork.DefaultUnitOfWork.notifyHandlers(DefaultUnitOfWork.java:109) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712668063Z at org.axonframework.messaging.unitofwork.AbstractUnitOfWork.changePhase(AbstractUnitOfWork.java:236) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712672023Z at org.axonframework.messaging.unitofwork.AbstractUnitOfWork.commitAsRoot(AbstractUnitOfWork.java:87) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712676036Z at org.axonframework.messaging.unitofwork.AbstractUnitOfWork.commit(AbstractUnitOfWork.java:75) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712679886Z at org.axonframework.messaging.unitofwork.DefaultUnitOfWork.executeWithResult(DefaultUnitOfWork.java:95) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712683896Z at org.axonframework.commandhandling.SimpleCommandBus.lambda$handle$2(SimpleCommandBus.java:200) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712687941Z at org.axonframework.tracing.Span.runSupplier(Span.java:163) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712691761Z at org.axonframework.commandhandling.SimpleCommandBus.handle(SimpleCommandBus.java:191) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712695731Z at org.axonframework.commandhandling.SimpleCommandBus.doDispatch(SimpleCommandBus.java:165) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712706291Z at org.axonframework.commandhandling.SimpleCommandBus.lambda$dispatch$1(SimpleCommandBus.java:131) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712710192Z at org.axonframework.tracing.Span.run(Span.java:101) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712714285Z at org.axonframework.commandhandling.SimpleCommandBus.dispatch(SimpleCommandBus.java:125) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712721526Z at org.axonframework.commandhandling.gateway.AbstractCommandGateway.send(AbstractCommandGateway.java:76) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712725899Z at org.axonframework.commandhandling.gateway.DefaultCommandGateway.send(DefaultCommandGateway.java:83) ~[axon-messaging-4.9.1.jar:4.9.1]
2024-02-05T10:40:47.712729740Z at org.axonframework.commandhandling.gateway.DefaultCommandGateway.sendAndWait(DefaultCommandGateway.java:100) ~[axon-messaging-4.9.1.jar:4.9.1]
The error seems related to recent changes in XStream and JDK 17.
That’s an example of an event in our application
@Builder
@Data
@Event
@XStreamAlias("JobCreatedEvent")
public class JobCreatedEvent implements Serializable {
private UUID jobId;
private String jobName;
@XStreamAlias("notificationInformation")
private NotificationInformation notificationInformation;
}
Questions:
- Considering the serialization issue, is using XStream within Axon Framework still possible?
- Is it now recommended to use Jackson instead of XStream for serialization within the Axon Framework?
- Can we seamlessly switch to Jackson while retaining the ability to deserialize events previously serialized with XStream in the same event store?
- Are Sagas also serialized using XStream, and would this be affected by the mentioned issue?
Thank you!