AWS Lambda errors with Java Lambdas and Serverless framework (502 Malformed Lambda proxy response)

Using a basic Servlerless framework event config like this:

functions:
  hello:
    handler: kh.javalambda.HelloLambda::myHandler
    events:
      - http:
        path: hello
        method: get 

…will create an API Gateway config with the Lambda Proxy feature enabled.

This sends the request as a JSON object to the Lambda. This includes HTTP headers, queryStringParameters, pathParameters and the request body. The Lambda is expected to have an appropriate parameter type for the incoming JSON payload otherwise you’ll get a Jackson parsing error like this:

An error occurred during JSON parsing: java.lang.RuntimeException
 java.lang.RuntimeException: An error occurred during JSON parsing
 Caused by: java.io.UncheckedIOException: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
  at [Source: lambdainternal.util.NativeMemoryAsInputStream@1bce4f0a; line: 1, column: 1]
 Caused by: com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of java.lang.String out of START_OBJECT token
  at [Source: lambdainternal.util.NativeMemoryAsInputStream@1bce4f0a; line: 1, column: 1

Use a Map<String, Object> as shown in the docs and the incoming request JSON will get passed in as this map.

Even if you are calling the Lambda with a GET request and not intending to POST or PUT a request body, you still need to have the Map<String, Object> parameter to receive the JSON event containing all the headers and params passed from API gateway.

Return Type

If you return a regular String or anything other than the expected response payload, from your Lambda will cause API Gateway to fail parsing the expected JSON response:

Wed Jan 13 07:34:32 UTC 2021 : Endpoint response body before transformations: "HelloLambda: hello null" Wed Jan 13 07:34:32 UTC 2021 : Execution failed due to configuration error: Malformed Lambda proxy response Wed Jan 13 07:34:32 UTC 2021 : Method completed with status: 502

With the API Gateway Lambda Proxy feature enabled, API Gateway expects response payloads from your Lambda to match the format shown here in the docs. Serverless framework generates a class called APIGatewayResponse that matches the expected format. Either create your own POJO that matches the expected return format or use the generated APIGatewayResponse class.

The generated sample Handler class shows this in use:

return ApiGatewayResponse.builder()
  .setStatusCode(200)
  .setObjectBody(responseBody)
  .setHeaders(Collections.singletonMap("X-Powered-By", "AWS Lambda & serverless"))
  .build(); 

Java Developer’s Journal Resource CD from 2004

I’ve got some weird stuff on my office bookshelf. While looking for something else, I came across this CD from 2004 which claims to have every issue of JDJ published, up until 2004. That can’t be that may so far, but apparently there was 85 issues up until this point.

“The Complete Works”!

Time to crack out the USB CD drive and see exactly what’s on this CD. I’ll post a follow up later with some examples what’s on the CD!

18 years ago the industry was questioning the longevity of Java … and it’s still going strong

In the April 2002 edition of the Java Developer Journal (which at that time was a major monthly publication in the Java world), the magazine editor wrote a column titled “There may be trouble ahead”, questioning how long Java had left. Funny thing is, this really does seem to be a perpetual question that gets asked every few years, and yet here we are 18 years later after this article was written, and Java has been going strong for 25 years.

This year Oracle in their role as stewards for the language (after Oracle bought Sun Microsystems in 2010), celebrated Java’s 25th year with a #MovedByJava social media campaign, looking back and encouraging others to share their stories and experiences from using Java over the past 25 years.

Java Developer Journal April 2002 – page 5
Java Developer Journal April 2002 – page 98

This column really has some dire predictions for the time, notably this prediction:

… 5 years? Wow.

Admittedly, the threat at that time that Microsoft’s .NET and the C# language in particular was going to take over the world was real, although Java still lived on to dominate severside processing for many years.

It sounds like at this time, Mono, the open source framework the article refers to was still in development, but even now that’s come and been around for a number of years this threat really came to nothing:

Even as Microsoft themselves have developed their own cross platform runtime for .NET apps on Windows, MacOS and Linux (.NET Core) clearly cashing in on the interest in Mono and Java’s own cross platform support with JVMs for every platform, again… this threat has still come to not much.

At the time this article was written in 2002 Java J2SE 1.4 was just released, and 18 years later we’re getting new major releases every 6 months and Java 15 was just released in September 2020, there’s clearly life in a 25 year old language yet.

Java 15 support in Eclipse

It used to be hit or miss and usually some delay before the latest Java version would get full new language feature support in the latest version of Eclipse. With these new Java version plugins from the Marketplace though, adding support is now as easy as installing the plugin:

The Eclipse team has been doing a great job with these plugins for latest language support.