Jackson deserialization of Saga AssociationValues

Hi,

Am new to Axon, and quite rusty with Java, but i’m having trouble getting the JacksonDeserializer to work with Sagas. I think it might need something special setting up in the Jackson ObjectMapper in the JacksonSerializer constructor to covert back from the AssociationValues interface to the AssociationValuesImpl?

The exception i’m getting is below. If anyone already had this configuration working, could you let me know, as I must be doing something else wrong? (I didn’t see this problem prior to adding the AMQP terminal to the eventBus.)

Thanks,

Steve

Caused by: org.axonframework.serializer.SerializationException: Error while deserializing object
at org.axonframework.serializer.json.JacksonSerializer.deserialize(JacksonSerializer.java:236)
at org.axonframework.saga.repository.jdbc.JdbcSagaRepository.load(JdbcSagaRepository.java:131)
at org.axonframework.saga.AbstractSagaManager.loadAndInvoke(AbstractSagaManager.java:246)
at org.axonframework.saga.AbstractSagaManager.invokeExistingSagas(AbstractSagaManager.java:141)
at org.axonframework.saga.AbstractSagaManager.handle(AbstractSagaManager.java:112)
at org.axonframework.eventhandling.SimpleCluster.doPublish(SimpleCluster.java:65)
at org.axonframework.eventhandling.AbstractCluster.publish(AbstractCluster.java:77)
at org.axonframework.eventhandling.amqp.spring.ClusterMessageListener.onMessage(ClusterMessageListener.java:64)
at org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:584)
… 10 common frames omitted
Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not construct instance of org.axonframework.saga.AssociationValues, problem: abstract types either need to be mapped to concrete types, have custom deserializer, or be instantiated with additional type information
at [Source: [B@f5fa199; line: 1, column: 2] (through reference chain: org.r3b.domain.OrderProcessSaga[“associationValues”])
at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)
at com.fasterxml.jackson.databind.DeserializationContext.instantiationException(DeserializationContext.java:771)
at com.fasterxml.jackson.databind.deser.AbstractDeserializer.deserialize(AbstractDeserializer.java:140)
at com.fasterxml.jackson.databind.deser.SettableBeanProperty.deserialize(SettableBeanProperty.java:538)
at com.fasterxml.jackson.databind.deser.impl.FieldProperty.deserializeAndSet(FieldProperty.java:106)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:238)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:118)
at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1269)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:912)
at org.axonframework.serializer.json.JacksonSerializer.deserialize(JacksonSerializer.java:234)
… 18 common frames omitted

Hi Steve,

it looks like the AssociationValues class is not compatible with (the default setup of) the JacksonSerializer. Jackson should be told how to (de)serialize an associationvalues class. This seems to be an issue in Axon itself. I will look into how one can create a module, so that the JacksonSerializer can (de)serialize them normally.

The XStreamSerializer works fine. As a workaround, you could use it for serializing Sagas. You can keep using the JacksonSerializer for the serialization of events.

Cheers,

Allard

Thanks! That got it working!

Hi allard,

We are using the axon framework and performing marshalling/unmarshalling using msgpack.We get the same exception but the problem is we switched over XStreamSerializer to msgpack as it is more compact, so we don’t want to revert to the Xstream serializer. So does the latest versions of axon has this issue resolved or we still have to use the XStreamSerializer for serializing Sagas.

Hi Anand,

it seems that the issue with the (de)serializer for AssociationValues hasn’t made it to the issue tracker, so it’s not fixed yet. I just reported it as AXON-332. The solution is to register a custom (de)serializer with Jackson, do that it can deserialize the AssociationValues.

Cheers,

Allard

Ok great,
Thanks Allard.

Hi allard,

I am using jackson to serialize/deserialize events and commands, as you said earlier in this mail chain about AXON-332 is it fixed now. Probably because when i asked the above question we were using version 2.4 but now as version 2.4.2 is released is the AssociationValues class now compatible with (the default setup of) the JacksonSerializer.

The reason i am asking the above question is i am facing a strange issue , ok let me tell a long story for this,

I am using my own serializer with jackson for serializing events and decleared it in the xml like ::

<axon:jdbc-event-store data-source=“dataSource” id=“eventStore” batch-size=“(‘jdbc.eventStore.batch.size’)”

event-serializer=“messageSerializer” sql-schema=“eventSqlSchema” force-utc-timestamp=“true” event-entry-store-ref=“customEventEntryStore”>

</axon:jdbc-event-store>

and basically messageSerializer is a bean provided by axon where i am passing my serializer in the constructor

I am using XstreamSerializer for serialization of saga

<axon:jdbc-saga-repository id=“sagaRepository” data-source=“dataSource”
resource-injector=“resourceInjector” saga-serializer=“xstreamSerializer”
sql-schema=“sagaSqlSchema”>
<axon:cache-config associations-cache=“sagaCacheRef” saga-cache=“associationCacheRef”/>
</axon:jdbc-saga-repository>

As both

  1. mySerializer

  2. XstreamSerializer

implements Serializer interface. I decleared mySerializer as primary (primary=“true” in spring-config).

The strange issue is when events come for deserialization i get the following exception by msgpack instance being passed in jackson ::

com.fasterxml.jackson.databind.JsonMappingException: Can not instantiate value of type [simple type, class CreatedEvent] from Integral number (60); no single-int-arg constructor/factory method
at [Source: [B@6295d394; line: -1, column: 0]

for days i was not able to know why it is asking for integer type constructor as there was no integer type value in this event.on analysis i found that the byte stream being serialized was like [60, 99, 111, 109, 46, 115, 112, 114, 105 and so on ] where 60 is the number for which it is complaining. Still for me number 60 was mysterious.
Then i further removed the msgpack instance and did the same deserialization with pure Jackson objectMapper. This time i got different exception ::

com.fasterxml.jackson.core.JsonParseException: Unexpected character (‘<’ (code 60)): expected a valid value (number, String, array, object, ‘true’, ‘false’ or ‘null’)
at [Source: [B@6121c9d6; line: 1, column: 2]

Now it became clear that from somewhere the byte stream coming for deserialization is XML data which is previously serialized ( I suppose xstreamSerializer has done that job ) but strangely for deserialization it has come on mySerializer class where jackson was expecting datatype other than Xml and hence was unable to deserialize.

My question is that is the serialization data not properly being sent by axon on the correct serializer as mySerializer and XstreamSerializer are of same type i.e both implement Serializer interface.

Hi,

the most common explanation is that some component still uses the XStream serializer. In the end, the XStream serializer always produces a result with the “<” as first character. Note that many components use XStream as default, so it’s possible the component at fault doesn’t have a serializer at all.

Cheers,

Allard

Hi Allard,

Thanks for your input, the question is can i use custom Jackson serializer for serialization of sagas ?

Because as i have stated the problem that the objects which are getting serialized by XStream are coming for deserialization on my custom defined Jackson class for Deserialization i am getting the above issue. I don’t know how the Xstream serailized data is coming for deserialization on custom defined Jackson serializer class’s deserialize method.
So if the sagas are also supported then i might expect that xml data doesn’t come as the serialization of even the sagas would be by Jackson. Please give some input on this.

Hi Allard,

Please ignore the strange issue i am talking about, on analysis i found that the records which were processed their payload was serialized by XstreamSerializer quite time back so they were old records because of which application was picking up that data and was complaining about xml. Can you please tell me if i can use custom Jackson serializer for serialization of sagas ?

Sorry for the inconvenience caused.

Hi Anand,

currently, Saga’s don’t seem to be suitable for serialization using Jackson. I can’t remember the details, but it had to do with the requirement for constructor parameters or setters that weren’t currently present. Since it requires an API change, we’ve had to postpone that to Axon 3.

Cheers,

Allard

Hi Allard,

I tried with jackson after clearing the SAGAENTRY and DOMAINEVENTENTRY table. I didn’t faced any exceptions or any issue uptil now but need your suggestion should i really go with jackson or revert back to Xstream for Saga’s . What say ?

Hi Anand,

I recall getting exceptions, but thay may have had to do with different configuration of Jackson. If it works for you, go for it. I have always prefered json over xml, but chose xstream as default because it can serialize any object out of the box.

Cheers,

Allard