Deploy Java Lambda functions with .zip or JAR file archives - AWS Lambda

Deploy Java Lambda functions with .zip or JAR file archives

Your AWS Lambda function's code consists of scripts or compiled programs and their dependencies. You use a deployment package to deploy your function code to Lambda. Lambda supports two types of deployment packages: container images and .zip file archives.

This page describes how to create your deployment package as a .zip file or Jar file, and then use the deployment package to deploy your function code to AWS Lambda using the AWS Command Line Interface (AWS CLI).

Prerequisites

The AWS CLI is an open-source tool that enables you to interact with AWS services using commands in your command line shell. To complete the steps in this section, you must have the AWS CLI version 2.

Tools and libraries

Lambda provides the following libraries for Java functions:

These libraries are available through Maven Central Repository. Add them to your build definition as follows:

Gradle
dependencies { implementation 'com.amazonaws:aws-lambda-java-core:1.2.2' implementation 'com.amazonaws:aws-lambda-java-events:3.11.1' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.1' }
Maven
<dependencies> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-core</artifactId> <version>1.2.2</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-events</artifactId> <version>3.11.1</version> </dependency> <dependency> <groupId>com.amazonaws</groupId> <artifactId>aws-lambda-java-log4j2</artifactId> <version>1.5.1</version> </dependency> </dependencies>

To create a deployment package, compile your function code and dependencies into a single .zip file or Java Archive (JAR) file. For Gradle, use the Zip build type. For Apache Maven, use the Maven Shade plugin. To upload your deployment package, use the Lambda console, the Lambda API, or AWS Serverless Application Model (AWS SAM).

Note

To keep your deployment package size small, package your function's dependencies in layers. Layers enable you to manage your dependencies independently, can be used by multiple functions, and can be shared with other accounts. For more information, see Managing Lambda dependencies with layers.

Building a deployment package with Gradle

To create a deployment package with your function's code and dependencies in Gradle, use the Zip build type. Here's an example from a complete sample build.gradle file:

Example build.gradle – Build task
task buildZip(type: Zip) { into('lib') { from(jar) from(configurations.runtimeClasspath) } }

This build configuration produces a deployment package in the build/distributions directory. Within the into('lib') statement, the jar task assembles a jar archive containing your main classes into a folder named lib. Additionally, the configurations.runtimeClassPath task copies dependency libraries from the build's classpath into the same lib folder.

Example build.gradle – Dependencies
dependencies { ... implementation 'com.amazonaws:aws-lambda-java-core:1.2.2' implementation 'com.amazonaws:aws-lambda-java-events:3.11.1' implementation 'org.apache.logging.log4j:log4j-api:2.17.1' implementation 'org.apache.logging.log4j:log4j-core:2.17.1' runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.17.1' runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.5.1' ... }

Lambda loads JAR files in Unicode alphabetical order. If multiple JAR files in the lib directory contain the same class, the first one is used. You can use the following shell script to identify duplicate classes:

Example test-zip.sh
mkdir -p expanded unzip path/to/my/function.zip -d expanded find ./expanded/lib -name '*.jar' | xargs -n1 zipinfo -1 | grep '.*.class' | sort | uniq -c | sort

Creating a Java layer for your dependencies

Note

Using layers with functions in a compiled language like Java may not provide the same amount of benefit as with an interpreted language like Python. Since Java is a compiled language, your functions still have to manually load any shared assemblies into memory during the init phase, which can increase cold start times. Instead, we recommend including any shared code at compile time to take advantage of any built-in compiler optimizations.

The instructions in this section show you how to include your dependencies in a layer. For instructions on how to include your dependencies in your deployment package, see Building a deployment package with Gradle or Building a deployment package with Maven.

When you add a layer to a function, Lambda loads the layer content into the /opt directory of that execution environment. For each Lambda runtime, the PATH variable already includes specific folder paths within the /opt directory. To ensure that the PATH variable picks up your layer content, your layer .zip file should have its dependencies in the following folder paths:

  • java/lib (CLASSPATH)

For example, your layer .zip file structure might look like the following:

jackson.zip └ java/lib/jackson-core-2.2.3.jar

In addition, Lambda automatically detects any libraries in the /opt/lib directory, and any binaries in the /opt/bin directory. To ensure that Lambda properly finds your layer content, you can also create a layer with the following structure:

custom-layer.zip └ lib | lib_1 | lib_2 └ bin | bin_1 | bin_2

After you package your layer, see Creating and deleting layers in Lambda and Adding layers to functions to complete your layer setup.

Building a deployment package with Maven

To build a deployment package with Maven, use the Maven Shade plugin. The plugin creates a JAR file that contains the compiled function code and all of its dependencies.

Example pom.xml – Plugin configuration
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> </execution> </executions> </plugin>

To build the deployment package, use the mvn package command.

[INFO] Scanning for projects... [INFO] -----------------------< com.example:java-maven >----------------------- [INFO] Building java-maven-function 1.0-SNAPSHOT [INFO] --------------------------------[ jar ]--------------------------------- ... [INFO] --- maven-jar-plugin:2.4:jar (default-jar) @ java-maven --- [INFO] Building jar: target/java-maven-1.0-SNAPSHOT.jar [INFO] [INFO] --- maven-shade-plugin:3.2.2:shade (default) @ java-maven --- [INFO] Including com.amazonaws:aws-lambda-java-core:jar:1.2.2 in the shaded jar. [INFO] Including com.amazonaws:aws-lambda-java-events:jar:3.11.1 in the shaded jar. [INFO] Including joda-time:joda-time:jar:2.6 in the shaded jar. [INFO] Including com.google.code.gson:gson:jar:2.8.6 in the shaded jar. [INFO] Replacing original artifact with shaded artifact. [INFO] Replacing target/java-maven-1.0-SNAPSHOT.jar with target/java-maven-1.0-SNAPSHOT-shaded.jar [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 8.321 s [INFO] Finished at: 2020-03-03T09:07:19Z [INFO] ------------------------------------------------------------------------

This command generates a JAR file in the target directory.

Note

If you're working with a multi-release JAR (MRJAR), you must include the MRJAR (i.e. the shaded JAR produced by the Maven Shade plugin) in the lib directory and zip it before uploading your deployment package to Lambda. Otherwise, Lambda may not properly unpack your JAR file, causing your MANIFEST.MF file to be ignored.

If you use the appender library (aws-lambda-java-log4j2), you must also configure a transformer for the Maven Shade plugin. The transformer library combines versions of a cache file that appear in both the appender library and in Log4j.

Example pom.xml – Plugin configuration with Log4j 2 appender
<plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.2.2</version> <configuration> <createDependencyReducedPom>false</createDependencyReducedPom> </configuration> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <transformers> <transformer implementation="com.github.edwgiz.maven_shade_plugin.log4j2_cache_transformer.PluginsCacheFileTransformer"> </transformer> </transformers> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>com.github.edwgiz</groupId> <artifactId>maven-shade-plugin.log4j2-cachefile-transformer</artifactId> <version>2.13.0</version> </dependency> </dependencies> </plugin>

Uploading a deployment package with the Lambda console

To create a new function, you must first create the function in the console, then upload your .zip or JAR file. To update an existing function, open the page for your function, then follow the same procedure to add your updated .zip or JAR file.

If your deployment package file is less than 50MB, you can create or update a function by uploading the file directly from your local machine. For .zip or JAR files greater than 50MB, you must upload your package to an Amazon S3 bucket first. For instructions on how to upload a file to an Amazon S3 bucket using the AWS Management Console, see Getting started with Amazon S3. To upload files using the AWS CLI, see Move objects in the AWS CLI User Guide.

Note

You cannot change the deployment package type (.zip or container image) for an existing function. For example, you cannot convert a container image function to use a .zip file archive. You must create a new function.

To create a new function (console)
  1. Open the Functions page of the Lambda console and choose Create Function.

  2. Choose Author from scratch.

  3. Under Basic information, do the following:

    1. For Function name, enter the name for your function.

    2. For Runtime, select the runtime you want to use.

    3. (Optional) For Architecture, choose the instruction set architecture for your function. The default architecture is x86_64. Ensure that the .zip deployment package for your function is compatible with the instruction set architecture you select.

  4. (Optional) Under Permissions, expand Change default execution role. You can create a new Execution role or use an existing one.

  5. Choose Create function. Lambda creates a basic 'Hello world' function using your chosen runtime.

To upload a .zip or JAR archive from your local machine (console)
  1. In the Functions page of the Lambda console, choose the function you want to upload the .zip or JAR file for.

  2. Select the Code tab.

  3. In the Code source pane, choose Upload from.

  4. Choose .zip or .jar file.

  5. To upload the .zip or JAR file, do the following:

    1. Select Upload, then select your .zip or JAR file in the file chooser.

    2. Choose Open.

    3. Choose Save.

To upload a .zip or JAR archive from an Amazon S3 bucket (console)
  1. In the Functions page of the Lambda console, choose the function you want to upload a new .zip or JAR file for.

  2. Select the Code tab.

  3. In the Code source pane, choose Upload from.

  4. Choose Amazon S3 location.

  5. Paste the Amazon S3 link URL of your .zip file and choose Save.

Uploading a deployment package with the AWS CLI

You can can use the AWS CLI to create a new function or to update an existing one using a .zip or JAR file. Use the create-function and update-function-code commands to deploy your .zip or JAR package. If your file is smaller than 50MB, you can upload the package from a file location on your local build machine. For larger files, you must upload your .zip or JAR package from an Amazon S3 bucket. For instructions on how to upload a file to an Amazon S3 bucket using the AWS CLI, see Move objects in the AWS CLI User Guide.

Note

If you upload your .zip or JAR file from an Amazon S3 bucket using the AWS CLI, the bucket must be located in the same AWS Region as your function.

To create a new function using a .zip or JAR file with the AWS CLI, you must specify the following:

  • The name of your function (--function-name)

  • Your function’s runtime (--runtime)

  • The Amazon Resource Name (ARN) of your function’s execution role (--role)

  • The name of the handler method in your function code (--handler)

You must also specify the location of your .zip or JAR file. If your .zip or JAR file is located in a folder on your local build machine, use the --zip-file option to specify the file path, as shown in the following example command.

aws lambda create-function --function-name myFunction \ --runtime java21 --handler example.handler \ --role arn:aws:iam::123456789012:role/service-role/my-lambda-role \ --zip-file fileb://myFunction.zip

To specify the location of .zip file in an Amazon S3 bucket, use the --code option as shown in the following example command. You only need to use the S3ObjectVersion parameter for versioned objects.

aws lambda create-function --function-name myFunction \ --runtime java21 --handler example.handler \ --role arn:aws:iam::123456789012:role/service-role/my-lambda-role \ --code S3Bucket=amzn-s3-demo-bucket,S3Key=myFileName.zip,S3ObjectVersion=myObjectVersion

To update an existing function using the CLI, you specify the the name of your function using the --function-name parameter. You must also specify the location of the .zip file you want to use to update your function code. If your .zip file is located in a folder on your local build machine, use the --zip-file option to specify the file path, as shown in the following example command.

aws lambda update-function-code --function-name myFunction \ --zip-file fileb://myFunction.zip

To specify the location of .zip file in an Amazon S3 bucket, use the --s3-bucket and --s3-key options as shown in the following example command. You only need to use the --s3-object-version parameter for versioned objects.

aws lambda update-function-code --function-name myFunction \ --s3-bucket amzn-s3-demo-bucket --s3-key myFileName.zip --s3-object-version myObject Version

Uploading a deployment package with AWS SAM

You can use AWS SAM to automate deployments of your function code, configuration, and dependencies. AWS SAM is an extension of AWS CloudFormation that provides a simplified syntax for defining serverless applications. The following example template defines a function with a deployment package in the build/distributions directory that Gradle uses:

Example template.yml
AWSTemplateFormatVersion: '2010-09-09' Transform: 'AWS::Serverless-2016-10-31' Description: An AWS Lambda application that calls the Lambda API. Resources: function: Type: AWS::Serverless::Function Properties: CodeUri: build/distributions/java-basic.zip Handler: example.Handler Runtime: java21 Description: Java function MemorySize: 512 Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambda_ReadOnlyAccess - AWSXrayWriteOnlyAccess - AWSLambdaVPCAccessExecutionRole Tracing: Active

To create the function, use the package and deploy commands. These commands are customizations to the AWS CLI. They wrap other commands to upload the deployment package to Amazon S3, rewrite the template with the object URI, and update the function's code.

The following example script runs a Gradle build and uploads the deployment package that it creates. It creates an AWS CloudFormation stack the first time you run it. If the stack already exists, the script updates it.

Example deploy.sh
#!/bin/bash set -eo pipefail aws cloudformation package --template-file template.yml --s3-bucket MY_BUCKET --output-template-file out.yml aws cloudformation deploy --template-file out.yml --stack-name java-basic --capabilities CAPABILITY_NAMED_IAM

For a complete working example, see the following sample applications:

Sample Lambda applications in Java
  • java17-examples – A Java function that demonstrates how to use a Java record to represent an input event data object.

  • java-basic – A collection of minimal Java functions with unit tests and variable logging configuration.

  • java-events – A collection of Java functions that contain skeleton code for how to handle events from various services such as Amazon API Gateway, Amazon SQS, and Amazon Kinesis. These functions use the latest version of the aws-lambda-java-events library (3.0.0 and newer). These examples do not require the AWS SDK as a dependency.

  • s3-java – A Java function that processes notification events from Amazon S3 and uses the Java Class Library (JCL) to create thumbnails from uploaded image files.

  • custom-serialization – Examples of how to implement custom serialization using popular libraries such as fastJson, Gson, Moshi, and jackson-jr.

  • Use API Gateway to invoke a Lambda function – A Java function that scans a Amazon DynamoDB table that contains employee information. It then uses Amazon Simple Notification Service to send a text message to employees celebrating their work anniversaries. This example uses API Gateway to invoke the function.