By Brian Fitzgerald
Introduction
This is a step-by-step procedure on how to create Scala AWS Lambda implementation in Eclipse with Maven. The compiled classes will run in the cloud in AWS Lambda’s java runtime environment (JRE).
Eclipse
To begin with, install these packages into your Eclipse, or check that they are installed:
- AWS Toolkit for Eclipse
- Scala IDE for Eclipse
Begin with Hello from Lambda!
The instructions in this section are based on the AWS manual. Setup AWS Toolkit for Eclipse.
Setup the AWS Lambda project
Click AWS Toolkit for Eclipse,
and select “New AWS Lambda Java project…” from the dropdown. In the dialog box, enter the project name, i.e. “FiboLam”, change “Input Type” from “S3 Event” to “Custom”, and press “Finish”.
Test the existing java function
Right click the project and select “Amazon Web Services” -> “Upload Function to AWS Lambda…”. In the dialog box, select “Create a new Lambda function:”. Enter a name and press “Next”. If you have not done so previously, create your role and S3 bucket. Press “Finish”.
Again, right click the project and select “Amazon Web Services” -> “Run function on AWS Lambda…”. Note that the Lambda Handler is in the form “package.class”, i.e. “com.amazonaws.lambda.demo.LambdaFunctionHandler”. Press “Invoke”. Check the console:
Skip uploading function code since no local change is found...
Invoking function...
==================== FUNCTION OUTPUT ====================
"Hello from Lambda!"
==================== FUNCTION LOG OUTPUT ====================
START RequestId: 45a20261-f9aa-4104-a0a3-b3a65cc37c07 Version: $LATEST
Input: {}END RequestId: 45a20261-f9aa-4104-a0a3-b3a65cc37c07
REPORT RequestId: 45a20261-f9aa-4104-a0a3-b3a65cc37c07 Duration: 0.74 ms Billed Duration: 100 ms Memory Size: 512 MB Max Memory Used: 82 MB
Up to here, we have a working AWS Lambda Java project.
Delete the existing java code
Now wipe out the java code
Expand src/main/java. Delete file LambdaFunctionHandler.java. Delete package com.example.lambda.demo
Expand src/test/java. You may delete file LambdaFunctionHandlerTest.java. Fixing it is out of scope for now.
Expand Maven Dependencies. You will see no scala runtime libraries, so far.
Scala
Add scala runtime library
Right click on the project, select “Configure->Add Scala Nature”
Refresh Maven Dependencies and take note of the version number, i.e. 2.12.3
Right click on the project and select “Maven”->”Add Dependency”, In the dialog box enter:
Group Id: org.scala-lang
Artifact Id: scala-library
Version: the version. i.e 2.12.3
Press “OK”
Expand Maven Dependencies. Note that the scala-library jar appears. A screenshot of the updated Maven tree appears later in this blog.
Create Scala Sources
Set scala perspective
Select Window->Perspective->Open Perspective->Other..” Scroll down and select “Scala”. Press “Open”
Create Scala classes
At “src/main/java”, you can create a new package, let’s say “com.yourcompany.fibo”. Then, create your scala source file. Select “New->Scala Class”, and enter the class name, i.e. “com.yourcompany.fibo.Fibo”.
Replace the code with:
import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler
class YourClass extends RequestHandler[Object, String] {
def handleRequest(o: Object, cx: Context): String =
yourCode
}
Method “handleRequest” is mandatory. In practice, input Object will be JSON serializable. The return must be of type String. For example, Fibo.scala:
package com.yourcompany.fibo
import com.amazonaws.services.lambda.runtime.Context
import com.amazonaws.services.lambda.runtime.RequestHandler
import com.yourcompany.fibo.FibTailRec.fib
class Fibo extends RequestHandler[Object, String] {
def handleRequest(o: Object, cx: Context): String =
fibTailRec(o.toString.toInt).toString
def fibTailRec(n: Int): Int =
fib(n, 0, 1)
}
press ctrl-S to save.
FibTailRec.scala
package com.yourcompany.fibo
import scala.annotation.tailrec
object FibTailRec {
@tailrec def fib(i: Int, p: Int, f: Int): Int = i match {
case 0 => {
p
}
case _ => fib(i - 1, f, p + f)
}
}
By the way, this function demonstrates Scala tail call optimization, and is examined in more detail here.
The project tree
Examine the Package Explorer. Expand src/main/java. Note that there is only your package, your sources, and no demo code. Expand Maven Dependencies. Note the scala library jar. Note that no folders or files are flagged with errors.
Upload the Lambda function
Right click the project and select “Amazon Web Services”->”Upload Function to AWS Lambda..”. Select the correct handler (there should be only one), i.e. “com.yourcompany.fibo.Fibo”. That way, AWS Lambda will automatically look to run method handleRequest. Choose existing Lambda Function: FiboLam
Run the Lambda function
Again, right click the project and select “Amazon Web Services” -> “Run function on AWS Lambda…”. Select your handler, i.e. “com.yourcompany.fibo.Fibo”. For the sake of this blog, we’re not going to delve into scala JSON parsing, so in the text pane, enter a nonnegative integer, i.e. 7. Press “Invoke”.
Output:
Skip uploading function code since no local change is found... Invoking function... ==================== FUNCTION OUTPUT ==================== "13" ==================== FUNCTION LOG OUTPUT ==================== START RequestId: 0f0990fe-497d-4f78-9709-5c67085d7a78 Version: $LATEST END RequestId: 0f0990fe-497d-4f78-9709-5c67085d7a78 REPORT RequestId: 0f0990fe-497d-4f78-9709-5c67085d7a78 Duration: 0.54 ms Billed Duration: 100 ms Memory Size: 512 MB Max Memory Used: 93 MB
Interpretation: 13 is the 7th Fibonacci number.
The upload file
You can go to your S3 bucket and find your file there (FiboLam.zip). You can download and explore the zip file and find your class files and the library jar files.
Summary
I have implemented a Scala AWS Lambda Function using these tools:
- Eclipse
- AWS Toolkit
- Scala IDE
- AWS
- Lambda Function
- IAM role
- S3 bucket
- Maven
The finished Lambda is made from only Scala classes. Now you can replace the Fibonacci code with your own code, and replace the test event with events from other AWS components in your own project.
