45
votes

I have written following Hello World Lambda which I am executing by uploading on AWS via AWS toolkit for Eclipse.

public class HelloWorldLambdaHandler implements RequestHandler<String, String> {
    public String handleRequest(String input, Context context) {
        System.out.println("Hello World! executed with input: " + input);
        return input;
    }
}

I am getting following error when executing above code. Any idea what I maybe doing wrong here? BTW Maven project which have this handler, doesn't have any other class and only dependency is aws-lambda-java-core version 1.1.0.

Skip uploading function code since no local change is found...
Invoking function...
==================== FUNCTION OUTPUT ====================
{"errorMessage":"An error occurred during JSON parsing","errorType":"java.lang.RuntimeException","stackTrace":[],"cause":{"errorMessage":"com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: lambdainternal.util.NativeMemoryAsInputStream@2f7c7260; line: 1, column: 1]","errorType":"java.io.UncheckedIOException","stackTrace":[],"cause":{"errorMessage":"Can not deserialize instance of java.lang.String out of START_OBJECT token\n at [Source: lambdainternal.util.NativeMemoryAsInputStream@2f7c7260; 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.deser.std.StringDeserializer.deserialize(StringDeserializer.java:59)","com.fasterxml.jackson.databind.deser.std.StringDeserializer.deserialize(StringDeserializer.java:12)","com.fasterxml.jackson.databind.ObjectReader._bindAndClose(ObjectReader.java:1441)","com.fasterxml.jackson.databind.ObjectReader.readValue(ObjectReader.java:1047)"]}}}
6
What payload are you using to test the invocation? - Will Hayworth
@WillHayworth Payload is empty JSON object ({}). - Hemant

6 Answers

88
votes

For some reason Amazon can't deserialize json to a String. You would think String would be as general as input parameter as you can get but rightly or wrongly it's not compatible.

To handle JSON you can either use a Map or a custom POJO.

public class HelloWorldLambdaHandler {
    public String handleRequest(Map<String,Object> input, Context context) {
        System.out.println(input);
        return "Hello";
    }
}
16
votes

Read the error from the stack trace. It says "Can not deserialize instance of java.lang.String out of START_OBJECT token". The "START_OBJECT" token is '{'.

The problem was simply that you need to pass an actual String as input, e.g., "A String". This is your json input. Not {}. {} is not a String. You don't need any braces, just a string (in quotes). On the other hand, {} is a valid Person object, so it worked once you changed it to handle a Person as the input.

12
votes

I tried with the following value in the test :

"TestInput"

instead of :

{ Input : "TestInput"}

and it seems to have worked fine.

3
votes

The complete working solution is

public class HelloWorldLambdaHandler implements RequestHandler<String, String> {
    public String handleRequest(String input, Context context) {
        System.out.println("Hello World! executed with input: " + input);
        return input;
    }
}

then input has to be in double quotes as a String - "Test Input"

0
votes

The input window for the test configurator takes raw json, or strings.

  • If you pass raw json, AWS converts the json into a Map where the variable names are keys that map the respective values.
  • If you wrap the json in double quotes and delimit inner quotes, this is an acceptable Java string representation of a json object and can be parsed as usual.
0
votes

Workaround 1:

Instead of

{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}

use some String as input, as shown below

"anyString"

It'll work fine.

Workaround 2: please refer the answer of @Lionel Port.

Reason:

As @Lionel Port suggested, you must be having String as inputType in your handleRequest() method!

public String handleRequest(String input, Context context) {}

you can see here, input type is String and you're passing Json, that's why giving this error!