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 files.
This page describes how to create a .zip file or Jar file your deployment package, and then use the .file to deploy your function code to AWS Lambda using the AWS Command Line Interface (AWS CLI). To upload your .zip file on the Lambda console, see Deployment packages.
Sections
Prerequisites
The AWS Command Line Interface (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 need the following:
Tools and libraries
Lambda provides the following libraries for Java functions:
-
com.amazonaws:aws-lambda-java-core
(required) – Defines handler method interfaces and the context object that the runtime passes to the handler. If you define your own input types, this is the only library that you need. -
com.amazonaws:aws-lambda-java-events
– Input types for events from services that invoke Lambda functions. -
com.amazonaws:aws-lambda-java-log4j2
– An appender library for Apache Log4j 2 that you can use to add the request ID for the current invocation to your function logs.
These libraries are available through Maven
Central Repository
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 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 Lambda layers.
Building a deployment package with Gradle
To create a deployment package with your function's code and dependencies, use the
Zip
build
type.
Example build.gradle – Build task
task buildZip(type: Zip) { from compileJava from processResources into('lib') { from configurations.runtimeClasspath } }
This build configuration produces a deployment package in the build/distributions
directory. The
compileJava
task compiles your function's classes. The processResources
task copies the Java project resources into their target directory, potentially processing
then. The statement into('lib')
then copies dependency libraries from the build's classpath into a folder named lib
.
Example build.gradle – Dependencies
dependencies { implementation platform('software.amazon.awssdk:bom:2.10.73') implementation 'software.amazon.awssdk:lambda'
implementation 'com.amazonaws:aws-lambda-java-core:1.2.1' implementation 'com.amazonaws:aws-lambda-java-events:3.1.0'
implementation 'com.google.code.gson:gson:2.8.6' implementation 'org.apache.logging.log4j:log4j-api:2.13.0' implementation 'org.apache.logging.log4j:log4j-core:2.13.0' runtimeOnly 'org.apache.logging.log4j:log4j-slf4j18-impl:2.13.0'runtimeOnly 'com.amazonaws:aws-lambda-java-log4j2:1.2.0'
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.6.0' testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.6.0' }
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
Building a deployment package with Maven
To build a deployment package with Maven, use the Maven Shade plugin
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.1 in the shaded jar. [INFO] Including com.amazonaws:aws-lambda-java-events:jar:3.1.0 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.
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 API
To update a function's code with the AWS Command Line Interface (AWS CLI) or AWS SDK,
use the UpdateFunctionCode API
operation. For the AWS CLI, use the update-function-code
command. The following command uploads a
deployment package named my-function.zip
in the current directory:
~/my-function$
aws lambda update-function-code --function-name my-function --zip-file fileb://my-function.zip
{ "FunctionName": "my-function", "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function", "Runtime": "java8", "Role": "arn:aws:iam::123456789012:role/lambda-role", "Handler": "example.Handler", "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=", "Version": "$LATEST", "TracingConfig": { "Mode": "Active" }, "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d", ... }
If your deployment package is larger than 50 MB, you can't upload it directly. Upload
it to an
Amazon Simple Storage Service (Amazon S3) bucket and point Lambda to the object. The
following example commands upload a deployment package
to an S3 bucket named my-bucket
and use it to update a function's code:
~/my-function$
aws s3 cp my-function.zip s3://my-bucket
upload: my-function.zip to s3://my-bucket/my-function ~/my-function$aws lambda update-function-code --function-name my-function \ --s3-bucket my-bucket --s3-key my-function.zip
{ "FunctionName": "my-function", "FunctionArn": "arn:aws:lambda:us-east-2:123456789012:function:my-function", "Runtime": "java8", "Role": "arn:aws:iam::123456789012:role/lambda-role", "Handler": "example.Handler", "CodeSha256": "Qf0hMc1I2di6YFMi9aXm3JtGTmcDbjniEuiYonYptAk=", "Version": "$LATEST", "TracingConfig": { "Mode": "Active" }, "RevisionId": "983ed1e3-ca8e-434b-8dc1-7d72ebadd83d", ... }
You can use this method to upload function packages up to 250 MB (decompressed).
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: java8 Description: Java function MemorySize: 512 Timeout: 10 # Function's execution role Policies: - AWSLambdaBasicExecutionRole - AWSLambdaReadOnlyAccess - 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
-
blank-java
– A Java function that shows the use of Lambda's Java libraries, logging, environment variables, layers, AWS X-Ray tracing, unit tests, and the AWS SDK. -
java-basic
– A minimal Java function with unit tests and variable logging configuration. -
java-events
– A minimal Java function that uses the aws-lambda-java-events library with event types that don't require the AWS SDK as a dependency, such as Amazon API Gateway. -
java-events-v1sdk
– A Java function that uses the aws-lambda-java-events library with event types that require the AWS SDK as a dependency (Amazon Simple Storage Service (Amazon S3), Amazon DynamoDB, and Amazon Kinesis). -
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.