I noticed that NodeJS is the only runtime option when creating an application.
https://us-east-2.console.aws.amazon.com/lambda/home?region=us-east-2#/create/application/configure
Is there a reason that NodeJS is the only option? I've heard that NodeJS is able to cold start faster than Java for lambdas. I also noticed the example Java lambda project defaults to 512MB MemorySize and NodeJS defaults to 128MB. Is Amazon trying to push us to NodeJS when building lambda applications because it's a better language for the environment?
Is it possible to create a Java lambda resource within the template.yml of an application? Do I need to build the classfiles and upload them manually?
The java-test
folder in my project has this structure
java-test/src/main/java/example/Handler.java
java-test/src/main/resources
java-test/build.gradle
I've tried the following Resource configuration, but the example.Handler class cannot be found.
javaTest:
Type: AWS::Serverless::Function
Properties:
CodeUri: java-test/
Handler: example.Handler
Runtime: java11
Description: Java function
MemorySize: 512
Timeout: 10
# Function's execution role
Policies:
- AWSLambdaBasicExecutionRole
- AWSLambda_ReadOnlyAccess
- AWSXrayWriteOnlyAccess
- AWSLambdaVPCAccessExecutionRole
Tracing: Active
I copied parts of the blank-java lambda project below.
https://github.com/awsdocs/aws-lambda-developer-guide/tree/main/sample-apps/blank-java
Here's the full build output
docker ps
"C:\Program Files\Amazon\AWSSAMCLI\bin\sam.cmd" build javaTest --template C:\Users\bensi\IdeaProjects\team-up\template.yml --build-dir C:\Users\bensi\IdeaProjects\team-up\.aws-sam\build --use-container
Starting Build inside a container
Building codeuri: C:\Users\bensi\IdeaProjects\team-up\java-test runtime: java11 metadata: {} architecture: x86_64 functions: ['javaTest']
Fetching public.ecr.aws/sam/build-java11:latest-x86_64 Docker container image......
Mounting C:\Users\bensi\IdeaProjects\team-up\java-test as /tmp/samcli/source:ro,delegated inside runtime container
Build Succeeded
Built Artifacts : .aws-sam\build
Built Template : .aws-sam\build\template.yaml
Commands you can use next
=========================
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {stack-name} --watch
[*] Deploy: sam deploy --guided
Running JavaGradleWorkflow:GradleBuild
Running JavaGradleWorkflow:CopyArtifacts
"C:\Program Files\Amazon\AWSSAMCLI\bin\sam.cmd" local invoke javaTest --template C:\Users\bensi\IdeaProjects\team-up\.aws-sam\build\template.yaml --event "C:\Users\bensi\AppData\Local\Temp\[Local] javaTest-event5.json"
Invoking example.Handler (java11)
Skip pulling image and use local one: public.ecr.aws/sam/emulation-java11:rapid-1.36.0-x86_64.
Mounting C:\Users\bensi\IdeaProjects\team-up\.aws-sam\build\javaTest as /var/task:ro,delegated inside runtime container
START RequestId: 3e9debb6-a640-4ba2-bd6e-5f2d818d303e Version: $LATEST
{"errorMessage":"Class not found: example.Handler","errorType":"java.lang.ClassNotFoundException"}Class not found: example.Handler: java.lang.ClassNotFoundException
java.lang.ClassNotFoundException: example.Handler. Current classpath: file:/var/task/:file:/var/task/lib/aws-lambda-java-core-1.2.1.jar:file:/var/task/lib/gson-2.8.6.jar
END RequestId: 3e9debb6-a640-4ba2-bd6e-5f2d818d303e
REPORT RequestId: 3e9debb6-a640-4ba2-bd6e-5f2d818d303e Init Duration: 0.07 ms Duration: 271.19 ms Billed Duration: 272 ms Memory Size: 512 MB Max Memory Used: 512 MB
I created the demo app and copied over the files in
./gradle/wrapper/
. It looks like the gradle jar needs to be uploaded with the source code of the project, but it's only 54KB so that's not too bad. I'll be checking out more of these quick start templates for other languages too. Thanks!I spoke too soon. I was able to upload the project, but when I invoke it I get the same error.
Here's the source code of the project I'm playing with https://github.com/bennebbenneb/sample-app
BTW when I run this project locally with
sam build && sam local start-api --host 0.0.0.0
I can invoke the Java endpoint and get the response back. It throws the class not found error when deployed to AWS.