Provides infrastructure layer compute capabilities, including both bare metal and virtual servers with various optimizations includins compute, memory, IO, and disk. Also supports accelerations options such as GPUs, FPGAs, Inferentia and Trainium.
Provides image recognition capability for images (in batch or real-time) and video that provides a analysis of the content such as real-world objects, faces, celebrities, and path mapping.
Provides a publish/subscribe notification service with multiple subscription types including Amazon Simple Queue Service (SQS), Amazon Kinesis Data Firehose, AWS Lambda, generic HTTPS endpoints, SMS and email.
A serverless, fully-managed, message queue service that supports producing, store, and consuming messages and enables loose coupling between applications.
Provides private networking capability spanning multiple availability zones and supporting subnets, routing, network access control groups, security groups and gateways.
Provides tracing of service invocations in distributed applications for observability, allowing users to diagnose issues or optimize their service interactions.
All about Cloud, mostly about Amazon Web Services (AWS)
Writing AWS Lambda functions in Java
2020-05-23 / 1569 words / 8 minutes
Although Python and JavaScript (via Node.js) seem to be the most popular programming languages for developing AWS Lambda functions, there are cases where Java must still be used. In these cases, it’s important to know about writing AWS Lambda functions in Java.
One example is in highly regulated industries with strict coding standards which may prevent dynamically typed languages like Python and JavaScript in favor of strongly typed languages like Java. Another example might be where code was previously written in Java and it rather than rewriting it in a different programming language and go through another cycle of bugfixes and redeployments it makes sense to convert the existing Java code to a Lambda function.
Typical Problems When Writing AWS Lambda functions in Java
Problems with writing AWS Lambda functions in Java seem to fall into several categories:
Build Pipeline and Cycle Time
Straight to CloudFormation
Development Approach
Build Pipeline and Cycle Time
Often in environments where Java will be used for Lambda functions, there will be a build pipeline which enforces corporate standards. Now, this is a good thing when there are enhancements or bugfixes being applied to code which has previously worked, but these build pipelines can introduces two major impediments when first writing AWS Lambda functions in Java.
First, there may be very specific rules which must be followed when configuring these build pipelines. The build pipeline may do deployments using AWS CloudFormation. It may be necessary to support multiple system levels (such as dev, test and production) and support multiple AWS regions (such as us-east-1 and us-west-2). There may be very specific subnets that the Lambda functions should be attached to, which may involve calling CloudFormation custom resources.
Second, since often the build system must be used to deploy in higher syslevels (such as test and prod), developers may only deploy through the build system. This means that rather than testing a changes from their local machine, they may commit a change, push it, then wait for the build pipeline to detect the change, and run through the CloudFormation create-stack or update-stack process. This is a problem that programming languages have solved with REPL (Read–eval–print loop) features.
Straight to CloudFormation
When the build system uses CloudFormation there is a tendancy to start writing CloudFormation. Although the AWS Console and AWS CLI might be available, they aren’t available when using higher syslevels (such as prod). Complex integration configuration between various AWS Services and AWS Lambda are developed in CloudFormation rather than first being tested in the AWS Management Console.
This makes the problem described in “Build Pipeline and Cycle Time” so much worse.
Development Approach
Java allows you to develop some very robust code. Interfaces and implementations allow levels of abstraction. Patterns like Factory Methods also hide unnecessary details from developers. As the codebase grows, these language features and development patterns become critical to ensuring the quality of the program.
I’ve seen situations though were I’ve been sent a URL to a git repository and asked if I can tell why the Lamdba function isn’t working. When I follow the link, there are a dozen classes and when I find one that implements the com.amazonaws.services.lambda.runtime.RequestHandler interface, it uses a bunch of Factory classes and layers of abstraction that need to be followed to figure out what is going on.
For sure, this would be less of a problem if an IDE such as IntelliJ, Eclipse or NetBeans were used to view the Lambda function, but the most minimal amount of code required to show success makes like easier even with IDEs.
My Approach to Writing AWS Lambda functions in Java
First, we need to build some Java code, so I start with a Maven pom.xml project file (although you may use Gradle, etc). I configure the Maven project with the Shade plugin, and run that locally. An example pom.xml file is:
I then test the build to ensure it works and then unpack the JAR using jar tvf to ensure that my Java class exists in the the JAR file. Typical output from the jar command is:
Next, we want to be able to make frequent repeatable updates to the Lambda function, so I develop a script that I can run locally that will build the code and register it as an AWS Lambda function. The prerequisite to this is an AWS Identity and Access Management (IAM) role but that can be created once in the AWS Console. The script runs the Maven build, deletes the old AWS Lambda function, then creates the new AWS Lambda function:
Once we run this script, we should see the AWS Lambda function in the AWS Console:
The next step is to test the Lambda function from the AWS Console. We can do this with the “Test” option. First we need to setup the test:
Once the test is defined, we can execute it. There is a expandable details section which provides more details:
We now have a working Lambda function. From this point, stepwise refinement is the key. There are several paths forward:
Improve the Lambda function itself, making the test JSON which is passed in more representative of what the Lambda function will actually receive and repeatedly improving the Lambda function, redeploying it using the script, and retesting it from the AWS Console.
Improve the integration. The work so far has provided a stable implementation to work with, but it isn’t tied to anything. I suggest using the AWS Console to attach the Lambda function to its trigger, such as an AWS Kinesis Data Stream, an Amazon Simple Queue Service (SQS) queue, or AWS CloudWatch Events / Amazon EventBridge. Once the integration is working in the AWS Console, try to replicate it using the AWS CLI, or AWS CloudFormation.
Switch from Lambda CLI to CloudFormation CLI. Calling AWS Lambda via the CLI provide very fast feedback, but if CloudFormation is used to deploy to production, there will be a point at which a CloudFormation template must be developed. A script can still be used to run the CloudFormation create-stack locally though to avoid the delay of committing the template, pushing it, and waiting for the build pipeline to process it. Simply update the shell script from AWS Lambda CLI calls to Amazon CloudFormation CLI calls.
I hope this makes writing AWS Lambda functions in Java a little more efficient!
All data and information provided on this site is for informational
purposes only. cloudninja.cloud makes no representations as to accuracy,
completeness, currentness, suitability, or validity of any information
on this site and will not be liable for any errors, omissions, or
delays in this information or any losses, injuries, or damages
arising from its display or use. All information is provided on an
as-is basis.
This is a personal weblog. The opinions expressed here represent my
own and not those of my employer. My opinions may change over time.