Write your first AWS Lambda in Java
Tags: java, aws, lamdba, serverless
Published: 2020-09-10 22:23:06

So far I have been writing Lambda function in Python for all my  AWS [projects](https://github.com/rajanpanchal) . In Python its easy, just import boto3 module and starting coding. Things are bit different when you write Lambda handlers in Java. Lets explore and see how you can write a simple HelloWorld Lambda handler in java. I have planned couple of how-to projects that I am going to write in Java. Hence I thought to do HelloWorld post before we dive into complex handlers. Feel free to follow me on [ twitter](https://twitter.com/PanchalRajan)  for upcoming updates.

To implement handler, we are going to use Maven, Eclipse and AWS SDK for Java. Below are the version:
- Java:  1.8
- Eclipse:  Version: 2020-06 (4.16.0)
- AWS SDK: 2.14.11
- Maven: 3.6.3 (Included with eclipse)

To get started, create a new empty maven project in eclipse. Go to File-> New-> Maven Project. In new project dialog box. select "create simple project" and hit next. On next screen. add appropriate information about the project and hit finish. For example:

 ![aws sdk java new maven project](https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-java/new-maven-project.PNG) 

Now your project is created. Open pom.xml and add following code.

```Pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>net.rajanpanchal</groupId>
	<artifactId>lambda-java-demo</artifactId>
	<version>1</version>
	<name>Lambda-Java-Demo</name>
	<description>HelloWorld Lambda handler in java</description>
	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<aws.java.sdk.version>2.14.11</aws.java.sdk.version>
	</properties>
	<dependencyManagement>
		<dependencies>
			<dependency>
				<groupId>software.amazon.awssdk</groupId>
				<artifactId>bom</artifactId>
				<version>${aws.java.sdk.version}</version>
				<type>pom</type>
				<scope>import</scope>
			</dependency>
		</dependencies>
	</dependencyManagement>
	<dependencies>
		<dependency>
			<groupId>com.amazonaws</groupId>
			<artifactId>aws-lambda-java-core</artifactId>
			<version>1.2.0</version>
		</dependency>

		<dependency>
			<groupId>com.google.code.gson</groupId>
			<artifactId>gson</artifactId>
			<version>2.8.6</version>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${maven.compiler.source}</source>
					<target>${maven.compiler.target}</target>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>3.2.4</version>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
					</execution>
				</executions>
			</plugin>
		</plugins>
	</build>
</project>

```
We are setting some properties in `<properties>` tag like AWS SDK version and Java Version. We are adding AWS SDK dependency and Lambda core dependency with desired version. Google JSON dependency is added to convert between JSON and Java object and vice versa.
In plugins, we define maven compiler plugin to compile the code and another important plugin called `maven-shade-plugin`. This plugin helps to create **fat jar** a.k.a **Uber jar**. This jar will contain all the dependencies that are required to successfully run the lambda function.

Now lets create the handler. 
``` Java
package net.rajanpanchal.handlers;

import java.util.Map;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.LambdaLogger;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;

public class HelloWorldHandler implements RequestHandler<Map<String,String>, String>{
	  Gson gson = new GsonBuilder().setPrettyPrinting().create();
	  @Override
	  public String handleRequest(Map<String,String> event, Context context)
	  {
	    LambdaLogger logger = context.getLogger();
	    String response = new String("200 OK");
	    // log execution details
	    logger.log("ENVIRONMENT VARIABLES: " + gson.toJson(System.getenv()));
	    logger.log("CONTEXT: " + gson.toJson(context));
	    // process event
	    logger.log("EVENT: " + gson.toJson(event));
	    logger.log("EVENT TYPE: " + event.getClass().toString());
	    return response;
	  }
	}
```
Here were are implementing `RequestHandler` that will accept a `Map` of `String` and outputs a `String` response. The handler is not doing much. Just logging some stuff from `context` and `event`  and in response it sends `200 OK` string.
After this right click on project, go to 'Run as' and click 'Maven build'. A configuration window will open. In 'Goals' type `package` and hit 'Run' . Build should be successful and will create a fat jar in `target` folder.

Now go to AWS console and create a new Lambda function with Java 8 as runtime and upload this jar from **Function Code** section. In Basic Settings, you have to specify package.class::methodName in the handler textbox. To test this Lambda, create a test event and execute the test.
 ![Java SDK Lambda Test Event](https://s3.amazonaws.com/blog-images-rajanpanchal.net/aws-sdk-java/test-event.PNG) 

The ouput might look similar to this:
```
START RequestId: c40b4095-27f5-4153-ac37-fd2c103f4476 Version: $LATEST
ENVIRONMENT VARIABLES: {
  "PATH": "/usr/local/bin:/usr/bin/:/bin:/opt/bin",
  "_AWS_XRAY_DAEMON_ADDRESS": "169.254.79.2",
  "LAMBDA_TASK_ROOT": "/var/task",
  "AWS_LAMBDA_FUNCTION_MEMORY_SIZE": "128",
  "TZ": ":UTC",
  "AWS_SECRET_ACCESS_KEY": "<keyid>",
  "AWS_EXECUTION_ENV": "AWS_Lambda_java8",
  "AWS_DEFAULT_REGION": "us-east-1",
  "AWS_LAMBDA_LOG_GROUP_NAME": "/aws/lambda/helloworldjava",
  "_HANDLER": "net.rajanpanchal.handlers.HelloWorldHandler::handleRequest",
  "LANG": "en_US.UTF-8",
  "LAMBDA_RUNTIME_DIR": "/var/runtime",
  "AWS_SESSION_TOKEN": "<session token>",
  "LD_LIBRARY_PATH": "/lib64:/usr/lib64:/var/runtime:/var/runtime/lib:/var/task:/var/task/lib:/opt/lib",
  "_X_AMZN_TRACE_ID": "Root\u003d1-5f545c5d-22c8a803badd636859a0f387;Parent\u003d23df427f78bc46e4;Sampled\u003d0",
  "AWS_SECRET_KEY": "<secret key>",
  "AWS_REGION": "us-east-1",
  "AWS_LAMBDA_LOG_STREAM_NAME": "2020/09/06/[$LATEST]57c598b33b164acf8e8151660249e50e",
  "AWS_XRAY_DAEMON_ADDRESS": "169.254.79.2:2000",
  "_AWS_XRAY_DAEMON_PORT": "2000",
  "AWS_XRAY_CONTEXT_MISSING": "LOG_ERROR",
  "AWS_LAMBDA_FUNCTION_VERSION": "$LATEST",
  "AWS_ACCESS_KEY": "<access key>",
  "AWS_LAMBDA_FUNCTION_NAME": "helloworldjava"
}CONTEXT: {
  "memoryLimit": 128,
  "awsRequestId": "c40b4095-27f5-4153-ac37-fd2c103f4476",
  "logGroupName": "/aws/lambda/helloworldjava",
  "logStreamName": "2020/09/06/[$LATEST]57c598b33b164acf8e8151660249e50e",
  "functionName": "helloworldjava",
  "functionVersion": "$LATEST",
  "invokedFunctionArn": "arn:aws:lambda:us-east-1:<AccountId>:function:helloworldjava",
  "cognitoIdentity": {
    "identityId": "",
    "poolId": ""
  },
  "logger": {}
}EVENT: {
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}EVENT TYPE: class java.util.LinkedHashMapEND RequestId: c40b4095-27f5-4153-ac37-fd2c103f4476
REPORT RequestId: c40b4095-27f5-4153-ac37-fd2c103f4476	Duration: 516.04 ms	Billed Duration: 600 ms	Memory Size: 128 MB	Max Memory Used: 79 MB	Init Duration: 393.54 ms
```

Here we complete our first Lambda handler in Java. In next post we will see how we can implement API using AWS SDK.