If I subscribe to an AWS lambda for SNS or SQS event, QuarkusStreamHandler could not deserialize the timestamp field from SNS class. It happens because the timestamp is using DateTime from JodaTime library and Jackson could not deserialize it correctly.
My stack trace
Cannot construct instance of `org.joda.time.DateTime` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('2019-12-11T13:29:08.731Z')
at [Source: (lambdainternal.util.NativeMemoryAsInputStream); line: 1, column: 429] (through reference chain: com.amazonaws.services.lambda.runtime.events.SNSEvent["Records"]->java.util.ArrayList[0]->com.amazonaws.services.lambda.runtime.events.SNSEvent$SNSRecord["Sns"]->com.amazonaws.services.lambda.runtime.events.SNSEvent$SNS["Timestamp"]): com.fasterxml.jackson.databind.exc.MismatchedInputException
com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot construct instance of `org.joda.time.DateTime` (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('2019-12-11T13:29:08.731Z')
at [Source: (lambdainternal.util.NativeMemoryAsInputStream); line: 1, column: 429] (through reference chain: com.amazonaws.services.lambda.runtime.events.SNSEvent["Records"]->java.util.ArrayList[0]->com.amazonaws.services.lambda.runtime.events.SNSEvent$SNSRecord["Sns"]->com.amazonaws.services.lambda.runtime.events.SNSEvent$SNS["Timestamp"])
at com.fasterxml.jackson.databind.exc.MismatchedInputException.from(MismatchedInputException.java:63)
at com.fasterxml.jackson.databind.DeserializationContext.reportInputMismatch(DeserializationContext.java:1342)
at com.fasterxml.jackson.databind.DeserializationContext.handleMissingInstantiator(DeserializationContext.java:1031)
at com.fasterxml.jackson.databind.deser.ValueInstantiator._createFromStringFallbacks(ValueInstantiator.java:371)
at com.fasterxml.jackson.databind.deser.std.StdValueInstantiator.createFromString(StdValueInstantiator.java:323)
at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromString(BeanDeserializerBase.java:1366)
at com.fasterxml.jackson.databind.deser.BeanDeserializer._deserializeOther(BeanDeserializer.java:171)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:161)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:286)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:245)
at com.fasterxml.jackson.databind.deser.std.CollectionDeserializer.deserialize(CollectionDeserializer.java:27)
at com.fasterxml.jackson.databind.deser.impl.MethodProperty.deserializeAndSet(MethodProperty.java:127)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.vanillaDeserialize(BeanDeserializer.java:288)
at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:151)
at com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1611)
at com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1188)
at io.quarkus.amazon.lambda.runtime.AmazonLambdaRecorder.handle(AmazonLambdaRecorder.java:65)
at io.quarkus.amazon.lambda.runtime.QuarkusStreamHandler.handleRequest(QuarkusStreamHandler.java:52)
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)
I'm having the same problem with the SNSEvent from aws-lambda-java-events. The library is quite convenient, so that one can avoid having to define the event classes anew.
I assumed that I'd be able to solve it by adding the JodaModule to a ObjectMapperCustomizer, to get the deserialisation working. But then I noticed that AmazonLambdaRecorder, which seems to be handling the invocations(?), uses its own ObjectMapper that can't be configured? Would be awesome if it used the one from quarkus-jackson as well, so that one can do additional configuration!
@dforsl would you like to give it a shot? That would be an awesome contribution!
@gsmet sure, would be fun! I'm completely swamped for this week, but I'll try to have a look next week.
Without really knowing anything, the BeanContainer looks interesting for this! I'll get back if I get the time.
@dforsl circling back to this one. Do you think you'll have a chance to submit a PR of this one? My team is hitting the same issue.
Most helpful comment
I'm having the same problem with the SNSEvent from
aws-lambda-java-events. The library is quite convenient, so that one can avoid having to define the event classes anew.I assumed that I'd be able to solve it by adding the
JodaModuleto aObjectMapperCustomizer, to get the deserialisation working. But then I noticed thatAmazonLambdaRecorder, which seems to be handling the invocations(?), uses its ownObjectMapperthat can't be configured? Would be awesome if it used the one fromquarkus-jacksonas well, so that one can do additional configuration!