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.

SerializationException when storing ScheduleToken in a Saga using JacksonSerializer

See original GitHub issue

The EventScheduler interface returns a ScheduleToken type as a return to schedule(). The problem is when a Saga is beign loaded, the token cannot be deserialized cause ScheduleToken is an abstract class.

Possible solutions are:

  • enable default typing on jackson (personally i don’t like this one)
  • provide JsonTypeInfo on ScheduleToken
  • implement a mechanism to provide own serializer/deserializer for ScheduleToken (possibly using previous approach as a default)

Below is a stack trace of an error.

org.axonframework.serialization.SerializationException: Error while deserializing object
	at org.axonframework.serialization.json.JacksonSerializer.deserialize(JacksonSerializer.java:214) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.saga.repository.jpa.JpaSagaStore.loadSaga(JpaSagaStore.java:150) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.saga.repository.AnnotatedSagaRepository.doLoadSaga(AnnotatedSagaRepository.java:251) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.saga.repository.AnnotatedSagaRepository.lambda$doLoad$1(AnnotatedSagaRepository.java:131) ~[axon-core-3.2.1.jar:3.2.1]
	at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660) ~[na:1.8.0_144]
	at org.axonframework.eventhandling.saga.repository.AnnotatedSagaRepository.doLoad(AnnotatedSagaRepository.java:130) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.saga.repository.AnnotatedSagaRepository.doLoad(AnnotatedSagaRepository.java:46) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.saga.repository.LockingSagaRepository.load(LockingSagaRepository.java:54) ~[axon-core-3.2.1.jar:3.2.1]
	at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193) ~[na:1.8.0_144]
	at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175) ~[na:1.8.0_144]
	at java.util.TreeMap$KeySpliterator.forEachRemaining(TreeMap.java:2746) ~[na:1.8.0_144]
	at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580) ~[na:1.8.0_144]
	at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270) ~[na:1.8.0_144]
	at java.util.HashMap$KeySpliterator.forEachRemaining(HashMap.java:1548) ~[na:1.8.0_144]
	at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481) ~[na:1.8.0_144]
	at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471) ~[na:1.8.0_144]
	at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[na:1.8.0_144]
	at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:1.8.0_144]
	at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499) ~[na:1.8.0_144]
	at org.axonframework.eventhandling.saga.AbstractSagaManager.handle(AbstractSagaManager.java:70) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.AbstractEventProcessor.lambda$null$2(AbstractEventProcessor.java:139) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:57) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.messaging.interceptors.CorrelationDataInterceptor.handle(CorrelationDataInterceptor.java:65) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.TrackingEventProcessor.lambda$new$1(TrackingEventProcessor.java:176) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.messaging.interceptors.TransactionManagingInterceptor.handle(TransactionManagingInterceptor.java:50) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.AbstractEventProcessor.lambda$processInUnitOfWork$3(AbstractEventProcessor.java:146) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.messaging.unitofwork.BatchingUnitOfWork.executeWithResult(BatchingUnitOfWork.java:80) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.AbstractEventProcessor.processInUnitOfWork(AbstractEventProcessor.java:135) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.TrackingEventProcessor.processBatch(TrackingEventProcessor.java:282) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.TrackingEventProcessor.processingLoop(TrackingEventProcessor.java:209) ~[axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.TrackingEventProcessor$TrackingSegmentWorker.run(TrackingEventProcessor.java:620) [axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.TrackingEventProcessor$WorkerLauncher.run(TrackingEventProcessor.java:713) [axon-core-3.2.1.jar:3.2.1]
	at org.axonframework.eventhandling.TrackingEventProcessor$CountingRunnable.run(TrackingEventProcessor.java:547) [axon-core-3.2.1.jar:3.2.1]
	at java.lang.Thread.run(Thread.java:748) [na:1.8.0_144]
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `org.axonframework.eventhandling.scheduling.ScheduleToken` (no Creators, like default construct, exist): abstract types either need to be mapped to concrete types, have custom deserializer, or contain additional type information
 at [Source: (byte[])"..."; line: 1, column: 176] (through reference chain: custis.modeus.notification.component.notification.command.saga.PersonNotificationPublishingSaga["retryToken"])
	at com.fasterxml.jackson.databind.exc.InvalidDefinitionException.from(InvalidDefinitionException.java:67) ~[jackson-databind-2.9.3.jar:2.9.3]
	at com.fasterxml.jackson.databind.DeserializationContext.reportBadDefinition(DeserializationContext.java:1451) ~[jackson-databind-2.9.3.jar:2.9.3]
	at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1027) ~[jackson-databind-2.9.3.jar:2.9.3]
	at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:265) ~[jackson-databind-2.9.3.jar:2.9.3]
	at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:136) ~[jackson-databind-2.9.3.jar:2.9.3]
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:287) ~[jackson-databind-2.9.3.jar:2.9.3]
	at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151) ~[jackson-databind-2.9.3.jar:2.9.3]
	at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1611) ~[jackson-databind-2.9.3.jar:2.9.3]
	at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1234) ~[jackson-databind-2.9.3.jar:2.9.3]
	at org.axonframework.serialization.json.JacksonSerializer.deserialize(JacksonSerializer.java:212) ~[axon-core-3.2.1.jar:3.2.1]

Issue Analytics

  • State:closed
  • Created 5 years ago
  • Reactions:1
  • Comments:7 (7 by maintainers)

github_iconTop GitHub Comments

1reaction
smcvbcommented, May 16, 2018

I follow your example @m1l4n54v1c, but serializing the token to Jackson is what’s currently not working, or only if you’ve introduced a solution like @vogoltsov shared with us. Thus the changes are pretty slim that adding the @JsonTypeInfo would case lots of backward compatibility issues, other than for @vogoltsov (sorry for that).

I’d assume that adding the type info is the simplest approach for now with I assume little impact for our users. Hope I’m right there 😉

0reactions
smcvbcommented, May 17, 2018

Resolved this issue in #598

Read more comments on GitHub >

github_iconTop Results From Across the Web

JpaSagaStore in conjunction with Jackson unable to properly ...
I've worked on Axon systems where the only used Serializer implementation was the JacksonSerializer too. Mind you though, this is not what ...
Read more >
JacksonSerializer.java example - Javatips.net
This class describes the usage of JacksonSerializer.java. ... Revisions are resolved using {@link * org.axonframework.serialization.
Read more >
Index (Axon Framework core 4.0-M2 API) - Javadoc.io
Initializes an event store with given storageEngine and NoOpMessageMonitor ... Java Persistence Entity allowing sagas to be stored in a relational database.
Read more >
PostgresSagaSqlSchema (Axon Framework 4.0 API)
Initialize a PostgresSagaSqlSchema using the given sagaSchema . ... Creates a PreparedStatement that creates the table for storing Sagas.
Read more >
Index (Axon Framework core 3.0-M2 API) - AppDoc
Initializes the SagaManager with the given sagaRepository . ... In-memory storage for AssociationValue to Saga mappings.
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