Closed AjitDas closed 3 years ago
Hi @AjitDas - what environment is this exception being thrown in? Was this running in Lambda or elsewhere?
Hi @carlzogh this error is coming on my local SAM testing, I have not deployed my code to AWS environment yet. Having said that I think this will come in AWS lambda env as well since serialization would be done same way just like my local SAM testing. Also FYI am using this along with spring framework. I was able to test with other type of events like SQSEvent
, SNSEvent
etc but for S3Event
it doesn't work due to jackson de serialization error.
I'm facing the same issue.
My workaround was to recompile com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification$S3EventNotificationRecord
with parameters since
https://docs.oracle.com/javase/tutorial/reflect/member/methodparameterreflection.html.
Maven has support for the switch so the workaround could be easily incorporated to the project by default.
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven.compiler.parameters>true</maven.compiler.parameters>
</properties>
Note that with older Jackson, one must have an accompanying module to support this (and of course take constructors with multiple parameters into consideration which Jackson doesn't do by default). I verified with it that the arguments got their names via refection by debugging com.fasterxml.jackson.module.paramnames.ParameterNamesAnnotationIntrospector
https://github.com/FasterXML/jackson-modules-java8/tree/master/parameter-names.
I forgot to mention that JsonCreator
from Jackson tag is still needed even when the parameter names are present and the binding would otherwise work. This is so that the de-serialization can deal with ambiguities (duplicate constructors etc.) and it's baked into how Jackson is meant to work.
Perhaps a pull request for Jackson's ParameterNamesAnnotationIntrospector
option would solve this that would make it to consider all constructors that are not deprecated as explicitly declared constructors. This would mimic the presence of the JsonCreator
without actually having the annotation present.
BTW: There's an alternative JDK7 based java.beans.ConstructorProperties
annotation via com.fasterxml.jackson.databind.ext.Java7Support
if direct Jackson dependency is a concern. I'm just afraid that this kind of binding would cause issues with java11 module system.
Having still the ability to parse InputStream
using the model would be great, but currently this is impossible without using own mixins etc to guide the process which would break easily whenever the model is updated.
There would be also the official JSON-B that give the capabilities analogous to what Jackson annotations used to provide in previous versions.
I think that even Jackson 2.11 could be then used as a JSON-P parser for Yasson that is the RI for the JSON-B standard.
I think this will resolve your problem.
https://github.com/aws/aws-lambda-java-libs/tree/master/aws-lambda-java-tests
I think what @CraigGoodspeed is trying to point out is this module:
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-serialization</artifactId>
<version>1.0.0</version>
</dependency>
Which you can use like this:
final PojoSerializer<S3EventNotification> s3EventSerializer =
LambdaEventSerializers.serializerFor(S3EventNotification.class, ClassLoader.getSystemClassLoader());
S3EventNotification eventNotification = s3EventSerializer.fromJson(message.body());
@rehevkor5 for some reason I was having trouble with that solution on the AWS lambda environment though it worked fine on my machine -- it couldn't find the S3EventNotification class. I tried a few things but in the end this worked for me, so I've settled for it:
S3EventNotification s3EventNotification = S3EventNotification.parseJson(snsMessage);
with the import
import com.amazonaws.services.s3.event.S3EventNotification;
though it meant I had to import the v1 SDK S3 library.
@rehevkor5
I think what @CraigGoodspeed is trying to point out is this module:
<dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-serialization</artifactId> <version>1.0.0</version> </dependency>
Which you can use like this:
final PojoSerializer<S3EventNotification> s3EventSerializer = LambdaEventSerializers.serializerFor(S3EventNotification.class, ClassLoader.getSystemClassLoader()); S3EventNotification eventNotification = s3EventSerializer.fromJson(message.body());
Thanks a lot, this saved me a lot of trouble.
@mo-rjr Use Thread.currentThread().getContextClassLoader()
instead of ClassLoader.getSystemClassLoader()
would solve this issue.
Ref: https://github.com/aws/aws-lambda-java-libs/issues/262#issuecomment-887005624
I am facing issue while de-serializing JSON to
S3Event
with Jackson APis throwing error because of non compliant POJO models for theseS3Event
classes.Error received after executing the S3Event JSON is something like this.
Can we have simple POJOs version of this
S3Event
so that it can be de-serialized accordingly.