├── project ├── build.properties ├── assembly.sbt └── Dependencies.scala ├── README.md ├── src ├── test │ └── scala │ │ └── example │ │ └── HelloSpec.scala └── main │ └── scala │ └── bootstrap │ └── Main.scala ├── .gitignore └── Dockerfile /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.1.1 2 | -------------------------------------------------------------------------------- /project/assembly.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.9") -------------------------------------------------------------------------------- /project/Dependencies.scala: -------------------------------------------------------------------------------- 1 | import sbt._ 2 | 3 | object Dependencies { 4 | lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.0.5" 5 | } 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # scala-graalvm-lambda 2 | 3 | Sample application of Native Scala with GraalVM. 4 | 5 | 6 | ## How to deploy to AWS Lambda 7 | 8 | 1. Run `$ sbt nativeCompile` 9 | 1. Upload zipped code (target/bundle.zip) into AWS Lambda 10 | -------------------------------------------------------------------------------- /src/test/scala/example/HelloSpec.scala: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import org.scalatest._ 4 | 5 | class HelloSpec extends FlatSpec with Matchers { 6 | "The Hello object" should "say hello" in { 7 | Hello.greeting shouldEqual "hello" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | 4 | # sbt specific 5 | .cache/ 6 | .history/ 7 | .lib/ 8 | dist/* 9 | target/ 10 | lib_managed/ 11 | src_managed/ 12 | project/boot/ 13 | project/plugins/project/ 14 | 15 | # Scala-IDE specific 16 | .scala_dependencies 17 | .worksheet 18 | .idea -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM oracle/graalvm-ce:1.0.0-rc15 2 | RUN yum install -y java-1.8.0-openjdk-headless \ 3 | && update-alternatives --set java $JAVA_HOME/bin/java \ 4 | && mv $JAVA_HOME/jre/lib/security/cacerts $JAVA_HOME/jre/lib/security/cacerts.bak \ 5 | && ln -s /usr/lib/jvm/jre-1.8.0/lib/security/cacerts $JAVA_HOME/jre/lib/security/cacerts 6 | 7 | CMD tail -f /dev/null -------------------------------------------------------------------------------- /src/main/scala/bootstrap/Main.scala: -------------------------------------------------------------------------------- 1 | package bootstrap 2 | 3 | import spray.json._ 4 | import scalaj.http._ 5 | 6 | object Main { 7 | 8 | def main(args: Array[String]): Unit = { 9 | val runtime = System.getenv("AWS_LAMBDA_RUNTIME_API") 10 | 11 | while (true) { 12 | val HttpResponse(body, _, headers) = Http(s"http://$runtime/2018-06-01/runtime/invocation/next").asString 13 | val requestId = headers("lambda-runtime-aws-request-id").head 14 | 15 | try { 16 | val name = body.parseJson.asJsObject.getFields("name").headOption match { 17 | case Some(JsString(value)) => value 18 | case _ => throw new Exception("unable to parse json") 19 | } 20 | val responseJson = JsObject("message" -> JsString(s"hello, $name!")).compactPrint 21 | Http(s"http://$runtime/2018-06-01/runtime/invocation/$requestId/response").postData(responseJson).asString 22 | } catch { 23 | case e: Exception => 24 | Http(s"http://$runtime/2018-06-01/runtime/invocation/$requestId/error").postData(e.getMessage).asString 25 | } 26 | } 27 | } 28 | } 29 | --------------------------------------------------------------------------------