AWS Developer Tools Blog
Bootstrapping a Java Lambda application with minimal AWS Java SDK startup time using Maven
We’re excited to share a new Maven Archetype for Java Lambda applications that we released recently and show you how to start building Java Lambda applications quickly, using this archetype. With the new archetype, customers can easily bootstrap a Java Lambda project configured with the AWS SDK for Java 2.x as a dependency and SAM template to deploy it to AWS Lambda. In addition, the generated application has SDK best-practices incorporated to achieve minimal SDK startup time. In this blog post, we will generate an application, build it, and deploy it to Lambda.
Prerequisites
To use this tutorial, you need to have the following software installed. This post assumes you have some familiarity with Java programming and the Maven build system.
Java 8
Apache Maven
AWS CLI
SAM CLI
Generating the application
To generate a project, open a terminal (command line) window and run mvn archetype:generate
command. There are two modes you can choose: interactive mode and batch mode.
- Interactive mode
In interactive mode, you’ll be prompted to provide required properties, one at a time.
mvn archetype:generate \ -DarchetypeGroupId=software.amazon.awssdk \ -DarchetypeArtifactId=archetype-lambda \ -DarchetypeVersion=2.15.79
- Batch mode
In batch mode, you need to provide all required properties at once. Below is the list of the required properties and you can check out all available options here.
Required Properties
-
- service: the service client to be used in the lambda function, eg: s3, dynamodb.
- region: the region to be set for the SDK client in the application
- groupId: the Maven group ID of the application
- artifactId: the Maven artifact ID of you application
The command below demonstrates creating an application that uses S3 SDK client configured with us-west-2
region. The artifactId of the project is test-project
and the groupId is com.amazon.test
.
mvn archetype:generate \ -DarchetypeGroupId=software.amazon.awssdk \ -DarchetypeArtifactId=archetype-lambda \ -DarchetypeVersion=2.15.79 \ -DgroupId=com.amazon.test \ -DartifactId=test-project \ -Dservice=s3 \ -Dregion=us-west-2 \ -DinteractiveMode=false
The output will be something like this:
[INFO] ---------------------------------------------------------------------------- [INFO] Using following parameters for creating project from Archetype: archetype-lambda:2.11.4 [INFO] ---------------------------------------------------------------------------- [INFO] Parameter: groupId, Value: com.amazon.test [INFO] Parameter: artifactId, Value: test-project [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] Parameter: package, Value: com.amazon.test [INFO] Parameter: packageInPathFormat, Value: com/amazon/test [INFO] Parameter: httpClient, Value: url-connection-client [INFO] Parameter: handlerClassName, Value: App [INFO] Parameter: groupId, Value: com.amazon.test [INFO] Parameter: service, Value: s3 [INFO] Parameter: version, Value: 1.0-SNAPSHOT [INFO] Parameter: nettyOpenSslVersion, Value: 2.0.29.Final [INFO] Parameter: javaSdkVersion, Value: 2.11.4 [INFO] Parameter: region, Value: us-west-2 [INFO] Parameter: package, Value: com.amazon.test [INFO] Parameter: artifactId, Value: test-project [INFO] Project created from Archetype in dir: /private/tmp/test-project [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 19.724 s [INFO] Finished at: 2020-03-30T16:10:12-07:00 [INFO] Final Memory: 20M/315M [INFO] ------------------------------------------------------------------------
When the archetype:generate
goal completes, you will have a Maven project with a dependency on the AWS Java SD 2.x and SDK client construction code with optimized configuration for Lambda. Below is the structure of the generated project from the command above.
test-project ├── README.md ├── pom.xml ├── src │ ├── main │ │ └── java │ │ └── com │ │ └── amazon │ │ └── test │ │ ├── App.java │ │ └── DependencyFactory.java │ └── test │ └── java │ └── com │ └── amazon │ └── test │ └── AppTest.java └── template.yaml
The App.java
class is the entry point for the Lambda function. The DependencyFactory.java
class contains the configured SDK client. The template.yaml
is a SAM template file where you can configure different properties of your lambda function, such as memory size and timeout.
Building the application
To build the application, run the following commands:
# Go to project directory created. # The name should be the same as the artifactId provided cd test-project # Build the application mvn clean install
Once it completes, it will generate a single JAR in the target folder. The JAR file contains the compiled function code and all of its dependencies, and it can be deployed to Lambda later.
The output will be something like the following
[INFO] Replacing /private/tmp/test-project/target/test-project.jar with /private/tmp/test-project/target/test-project-1.0-SNAPSHOT-shaded.jar [INFO] [INFO] --- maven-install-plugin:2.4:install (default-install) @ test-project --- [INFO] Installing /private/tmp/test-project/target/test-project-1.0-SNAPSHOT.jar to /Users/zoewang/.m2/repository/com/amazon/test/test-project/1.0-SNAPSHOT/test-project-1.0-SNAPSHOT.jar [INFO] Installing /private/tmp/test-project/pom.xml to /Users/zoewang/.m2/repository/com/amazon/test/test-project/1.0-SNAPSHOT/test-project-1.0-SNAPSHOT.pom [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 5.214 s [INFO] Finished at: 2020-03-30T16:10:44-07:00 [INFO] Final Memory: 31M/253M
To test the generated Lambda function locally with SAM CLI , you can run the following command.
sam local invoke
This command executes the Lambda function locally and is useful to verify that the function works before deploying it to AWS Lambda. The output looks like this
END RequestId: cbdf9d00-983b-1c9a-1380-6785a57af655 REPORT RequestId: cbdf9d00-983b-1c9a-1380-6785a57af655 Init Duration: 3930.21 ms Duration: 89.91 ms Billed Duration: 100 ms Memory Size: 512 MB Max Memory Used: 74 MB {}
Deployment
To deploy the application, you can run the following command. You can learn more about sam deploy here.
sam deploy --guided
The guided prompts will first ask you to provide configurations regarding the deployment. The output will be something like this
$ test-project sam deploy --guided Configuring SAM deploy ====================== Looking for samconfig.toml : Not found Setting default arguments for 'sam deploy' ========================================= Stack Name [sam-app]: test-project AWS Region [us-east-1]: us-west-2 #Shows you resources changes to be deployed and require a 'Y' to initiate deploy Confirm changes before deploy [y/N]: y #SAM needs permission to be able to create roles to connect to the resources in your template Allow SAM CLI IAM role creation [Y/n]: y Save arguments to samconfig.toml [Y/n]: y
After that, it will create a CloudFormation changeset for your Lambda function. Once you confirm to deploy the changeset, it will create the resources needed and deploy your Lambda function.
Previewing CloudFormation changeset before deployment ====================================================== Deploy this changeset? [y/N]: y 2020-04-01 13:42:20 - Waiting for stack create/update to complete CloudFormation events from changeset ------------------------------------------------------------------------------------------------------------------------------------------------------------- ResourceStatus ResourceType LogicalResourceId ResourceStatusReason ------------------------------------------------------------------------------------------------------------------------------------------------------------- CREATE_IN_PROGRESS AWS::IAM::Role AppFunctionRole - CREATE_IN_PROGRESS AWS::IAM::Role AppFunctionRole Resource creation Initiated CREATE_COMPLETE AWS::IAM::Role AppFunctionRole - CREATE_IN_PROGRESS AWS::Lambda::Function AppFunction - CREATE_IN_PROGRESS AWS::Lambda::Function AppFunction Resource creation Initiated CREATE_COMPLETE AWS::Lambda::Function AppFunction - CREATE_COMPLETE AWS::CloudFormation::Stack test-project - ------------------------------------------------------------------------------------------------------------------------------------------------------------- Successfully created/updated stack - test-project in us-west-2
Once it’s done, you can verify that the resources are created by running the following command:
aws cloudformation describe-stack-resource --stack-name=test-project --logical-resource-id=AppFunction --query=StackResourceDetail.PhysicalResourceId
It will print out the name of the Lambda Function just created. To invoke the Lambda Function from the command line, copy the function name and run the following command:
aws lambda invoke —function-name=<FunctionName> response.json
The output will be something like this
{ "StatusCode": 200, "ExecutedVersion": "$LATEST" }
Clean Up
If you no longer need the resources, you can remove them by deleting the AWS CloudFormation stack using the following command:
aws cloudformation delete-stack —stack-name test-project
To verify the stack is delete, you need to run the following command and make sure the stack name you entered above is in the output
aws cloudformation list-stacks —stack-status-filter DELETE_COMPLETE
Conclusion
Archetypes codify best practices, and in this blog post we showed you how natural, and quick it is to get started with these Java Lambda templates using Maven. If you want to learn more about the Archetype, you can check out the archetype-lambda source code on Github. Please give this new archetype a try and let us know what you think via the GitHub issues page.