Replaying events invokes event handler for SerializedDomainEventMessage instead of actual type, is this as expected?

Hello, Im new to the Axon framework and I seem to have a couple of issues grasping how replaying events works.

Given that i have several PersonCreatedEvent events persisted in the event store, when replaying events i would expect the following piece of code to be invoked.

@EventHandler
void on(PersonCreatedEvent event) {
this.id = event.getId();
this.firstName = event.getFirstName();
this.lastName = event.getLastName();
PersonResource.PERSONS.put(this.id,this);
}

However this doesn’t occur. Instead if i create a event handler with the following signature.

@EventHandler
void on(Message message){

}

The handler is executed and i can see that im receiving a SerializedDomainEventMessage. Now the weird part is that i can see through debugging the code that the event message has a getPayload and a getPayloadType method, which gives me the correct instance and type of PersonCreatedEvent… However the following statements still yield false when i would have expected true…

message.getPayloadType().equals(PersonCreatedEvent.class) // false
message.getPayload() instanceof PersonCreatedEvent // false

So, what am i doing wrong here? How can i replay events so that my PersonCreatedEvent handler get’s invoked?

The following is my axon configuration (im using spring boot with axon and a mongo event store)

@Configuration
@AnnotationDriven
public class AxonConfiguration {

@Bean(“replay”)
public ReplayingCluster replayCluster(){
return new ReplayingCluster(
new SimpleCluster(“simple”),
eventStore(),
new NoTransactionManager(),
0,
new BackloggingIncomingMessageHandler()
);
}

@Bean
public Mongo mongo(){
try {
return new Mongo(“localhost”);
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
}

@Bean
public AnnotationEventListenerBeanPostProcessor annotationEventListenerBeanPostProcessor() {
AnnotationEventListenerBeanPostProcessor processor = new AnnotationEventListenerBeanPostProcessor();
processor.setEventBus(eventBus());
return processor;
}

@Bean
public AnnotationCommandHandlerBeanPostProcessor annotationCommandHandlerBeanPostProcessor() {
AnnotationCommandHandlerBeanPostProcessor processor = new AnnotationCommandHandlerBeanPostProcessor();
processor.setCommandBus(commandBus());
return processor;
}

@Bean
public CommandBus commandBus() {
SimpleCommandBus commandBus = new SimpleCommandBus();
commandBus.setHandlerInterceptors(Arrays.asList(new BeanValidationInterceptor()));
return commandBus;
}

@Bean
public EventBus eventBus() {
return new ClusteringEventBus(new DefaultClusterSelector(replayCluster()));
}

@Bean
public CommandGatewayFactoryBean commandGatewayFactoryBean() {
CommandGatewayFactoryBean factory = new CommandGatewayFactoryBean<>();
factory.setCommandBus(commandBus());
return factory;
}

@Bean
public MongoEventStore eventStore(){
return new MongoEventStore(new DefaultMongoTemplate(mongo()));
}

@Bean
public EventSourcingRepository personEventSourcingRepository() {
EventSourcingRepository repository = new EventSourcingRepository<>(Person.class, eventStore());
repository.setEventBus(eventBus());
return repository;
}

@Bean
public AggregateAnnotationCommandHandler personAggregateAnnotationCommandHandler() {
return AggregateAnnotationCommandHandler.subscribe(Person.class, personEventSourcingRepository(), commandBus());
}

As a followup the issue with checking the class instance which yields false seem to be because of different classloaders…

java.lang.ClassCastException: com.example.user.event.PersonCreatedEvent cannot be cast to com.example.user.event.PersonCreatedEvent