I have an application with Spring Integration that queues incoming messages in a PriorityChannel which are persisted using a messageStore using MongoDbChannelMessageStore implementation. Currently we are under Springboot 2.1.3 version. And we make all the necessary changes to go to 2.5.4 version. Many changes in build.gradle, AWS package refactor etc, etc... no problem with this and everything works as expected.
The specific problem is that if I want to upgrade having stored incoming messages with the older version in production, when the application with the new version continues to process this load the following error occurrs. Seems to be a convertion from spring integration that goes wrong. Any advice please?
2022-01-12 16:41:27,214 [1;31mERROR[0;39m [36m[org.springframework.integration.handler.LoggingHandler catalogue-pool-1 ][0;39m org.springframework.messaging.MessagingException: nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [org.bson.types.Binary] to type [org.springframework.messaging.Message<?>] for value 'org.bson.types.Binary@fb62eb16'; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.InvalidClassException: org.springframework.util.LinkedCaseInsensitiveMap; local class incompatible: stream classdesc serialVersionUID = -798892522772790821, local class serialVersionUID = 1755438538721305358
at org.springframework.integration.endpoint.AbstractPollingEndpoint.pollForMessage(AbstractPollingEndpoint.java:427)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.lambda$createPoller$4(AbstractPollingEndpoint.java:348)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.lambda$execute$0(ErrorHandlingTaskExecutor.java:57)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: org.springframework.core.convert.ConversionFailedException: Failed to convert from type [org.bson.types.Binary] to type [org.springframework.messaging.Message<?>] for value 'org.bson.types.Binary@fb62eb16'; nested exception is org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.InvalidClassException: org.springframework.util.LinkedCaseInsensitiveMap; local class incompatible: stream classdesc serialVersionUID = -798892522772790821, local class serialVersionUID = 1755438538721305358
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:47)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:192)
at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:175)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.doConvert(MappingMongoConverter.java:1546)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.doConvert(MappingMongoConverter.java:1538)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:1048)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.getPotentiallyConvertedSimpleRead(MappingMongoConverter.java:1033)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$ConversionContext.convert(MappingMongoConverter.java:1891)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$MongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1640)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$AssociationAwareMongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1689)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter$AssociationAwareMongoDbPropertyValueProvider.getPropertyValue(MappingMongoConverter.java:1652)
at org.springframework.data.mapping.model.PersistentEntityParameterValueProvider.getParameterValue(PersistentEntityParameterValueProvider.java:74)
at org.springframework.data.mapping.model.SpELExpressionParameterValueProvider.getParameterValue(SpELExpressionParameterValueProvider.java:53)
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.extractInvocationArguments(ClassGeneratingEntityInstantiator.java:269)
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator$EntityInstantiatorAdapter.createInstance(ClassGeneratingEntityInstantiator.java:241)
at org.springframework.data.mapping.model.ClassGeneratingEntityInstantiator.createInstance(ClassGeneratingEntityInstantiator.java:89)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:368)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.readDocument(MappingMongoConverter.java:341)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:277)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:273)
at org.springframework.data.mongodb.core.convert.MappingMongoConverter.read(MappingMongoConverter.java:102)
at org.springframework.data.mongodb.core.MongoTemplate$ReadDocumentCallback.doWith(MongoTemplate.java:3178)
at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java:2771)
at org.springframework.data.mongodb.core.MongoTemplate.doFindAndRemove(MongoTemplate.java:2659)
at org.springframework.data.mongodb.core.MongoTemplate.findAndRemove(MongoTemplate.java:1089)
at org.springframework.integration.mongodb.store.MongoDbChannelMessageStore.pollMessageFromGroup(MongoDbChannelMessageStore.java:142)
at org.springframework.integration.store.MessageGroupQueue.doPoll(MessageGroupQueue.java:357)
at org.springframework.integration.store.MessageGroupQueue.poll(MessageGroupQueue.java:192)
at org.springframework.integration.store.MessageGroupQueue.poll(MessageGroupQueue.java:51)
at org.springframework.integration.channel.QueueChannel.doReceive(QueueChannel.java:144)
at org.springframework.integration.channel.PriorityChannel.doReceive(PriorityChannel.java:138)
at org.springframework.integration.channel.AbstractPollableChannel.receive(AbstractPollableChannel.java:95)
at org.springframework.integration.endpoint.PollingConsumer.receiveMessage(PollingConsumer.java:217)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:444)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.pollForMessage(AbstractPollingEndpoint.java:413)
... 5 more
Caused by: org.springframework.core.serializer.support.SerializationFailedException: Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; nested exception is java.io.InvalidClassException: org.springframework.util.LinkedCaseInsensitiveMap; local class incompatible: stream classdesc serialVersionUID = -798892522772790821, local class serialVersionUID = 1755438538721305358
at org.springframework.integration.support.converter.AllowListDeserializingConverter.convert(AllowListDeserializingConverter.java:142)
at org.springframework.integration.mongodb.support.BinaryToMessageConverter.convert(BinaryToMessageConverter.java:38)
at org.springframework.integration.mongodb.support.BinaryToMessageConverter.convert(BinaryToMessageConverter.java:31)
at org.springframework.core.convert.support.GenericConversionService$ConverterAdapter.convert(GenericConversionService.java:386)
at org.springframework.core.convert.support.ConversionUtils.invokeConverter(ConversionUtils.java:41)
... 39 more
Caused by: java.io.InvalidClassException: org.springframework.util.LinkedCaseInsensitiveMap; local class incompatible: stream classdesc serialVersionUID = -798892522772790821, local class serialVersionUID = 1755438538721305358
at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:699)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:2001)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1848)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2158)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2403)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2327)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2185)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2403)
at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:631)
at org.springframework.util.MimeType.readObject(MimeType.java:598)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1185)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2294)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2185)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:501)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:459)
at java.util.HashMap.readObject(HashMap.java:1412)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1185)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2294)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2185)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2403)
at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:631)
at org.springframework.messaging.MessageHeaders.readObject(MessageHeaders.java:329)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1185)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2294)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2185)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2403)
at java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:631)
at org.springframework.messaging.MessageHeaders.readObject(MessageHeaders.java:329)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1185)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2294)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2185)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2403)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2327)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2185)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1665)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:501)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:459)
at org.springframework.integration.support.converter.AllowListDeserializingConverter.deserialize(AllowListDeserializingConverter.java:160)
at org.springframework.integration.support.converter.AllowListDeserializingConverter.convert(AllowListDeserializingConverter.java:133)
... 43 more
Yeah... Looks like some org.springframework.util.LinkedCaseInsensitiveMap
class internal state has been changed in between and its previously serialized version is not compatible with what a new app is expecting.
You probably need to implement and Adapter application which would be based on an old version of Spring Boot. Offloads those messages, removes (or convert) the header with that org.springframework.util.MimeType
value and serializes them back to the queue for a new app.
I don't think it really have a significant value to really store the whole org.springframework.util.MimeType
, but not just its plain string representation...