2
votes

I have found new information.I think maybe I have implemented the incorrect interface for my S3 event source. I so far have not been able to get it to work or understand which interface should be implemented if any. The RequestHandler interface requires the method handleRequest to return a value. Any suggestions?

outputType – If you plan to invoke the Lambda function synchronously (using the RequestResponse invocation type), you can return the output of your function using any of the supported data types. For example, if you use a Lambda function as a mobile application backend, you are invoking it synchronously. Your output data type will be serialized into JSON.

If you plan to invoke the Lambda function asynchronously (using the Event invocation type), the outputType should be void. For example, if you use AWS Lambda with event sources such as Amazon S3, Amazon Kinesis, and Amazon SNS, these event sources invoke the Lambda function using the Event invocation type.

I have created a basic handler but seem to have missed a critical step that continues to allude me.

Code & Error below:

package example;

import com.amazonaws.services.lambda.runtime.Context; 
import com.amazonaws.services.lambda.runtime.LambdaLogger; 
import com.amazonaws.services.lambda.runtime.RequestHandler; 
import com.amazonaws.services.s3.model.S3Event;

public class Hello implements RequestHandler<S3Event, Object> {
    public String handleRequest(S3Event input, Context context) {
        return "Hello";
    } 
}

{ "errorMessage": "An error occurred during JSON parsing",
"errorType": "java.lang.RuntimeException", "stackTrace": [],
"cause": { "errorMessage": "com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.amazonaws.services.s3.model.S3Event out of START_OBJECT token\n at Source: lambdainternal.util.NativeMemoryAsInputStream@566776ad; line: 1, column: 1", "errorType": "java.io.UncheckedIOException", "stackTrace": [], "cause": { "errorMessage": "Can not deserialize instance of com.amazonaws.services.s3.model.S3Event out of START_OBJECT token\n at Source: lambdainternal.util.NativeMemoryAsInputStream@566776ad; line: 1, column: 1", "errorType": "com.fasterxml.jackson.databind.JsonMappingException", "stackTrace": [ "com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:148)", "com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:835)", "com.fasterxml.jackson.databind.DeserializationContext.mappingException(DeserializationContext.java:831)", "com.fasterxml.jackson.databind.deser.std.EnumDeserializer._deserializeOther(EnumDeserializer.java:137)", "com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:89)", "com.fasterxml.jackson.databind.deser.std.EnumDeserializer.deserialize(EnumDeserializer.java:18)", "com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1441)", "com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1047)"] } } }

4
I think you are supposed to return a value that can be serialized to a JSON object. "Hello" is not valid. - garnaat

4 Answers

2
votes

Check if you're importing the right S3Event class, which is com.amazonaws.services.lambda.runtime.events.S3Event.

I got the same exception, and find out I've been imported com.amazonaws.services.s3.model.S3Event.

0
votes

Make the return type of method handleRequest() as Object and you can return "Hello" too.

0
votes

The error message you got

Can not deserialize instance of com.amazonaws.services.s3.model.S3Event out of START_OBJECT token

means that the value passed as the input parameter to your Lambda function doesn't represent an S3Event object.

Were you testing your Lambda function from the AWS console, as opposed to triggering a real S3 event?
If so, go to Lambda > Functions > yourFunction > Actions > Configure test event and select either S3 Put or S3 Delete from the Sample event template dropdown to send the proper input to your function for the test.

0
votes

I think you can't return a non object response. You could do something like this:

return new Gson().fromJson(jsonObject, Object.class);

Note: jsonObject is a json that contains information that you want to return.