diff --git a/.github/workflows/aws-lambda-java-runtime-interface-client.yml b/.github/workflows/aws-lambda-java-runtime-interface-client.yml
index 15d5921d..6b3ab3a6 100644
--- a/.github/workflows/aws-lambda-java-runtime-interface-client.yml
+++ b/.github/workflows/aws-lambda-java-runtime-interface-client.yml
@@ -29,4 +29,3 @@ jobs:
- name: Run 'pr' target
working-directory: ./aws-lambda-java-runtime-interface-client
run: make pr
-
diff --git a/.gitignore b/.gitignore
index fbdc4bbe..739a59d8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -21,4 +21,7 @@ dependency-reduced-pom.xml
.gradle
.settings
.classpath
-.project
\ No newline at end of file
+.project
+
+#MacOS
+.DS_Store
\ No newline at end of file
diff --git a/aws-lambda-java-core/pom.xml b/aws-lambda-java-core/pom.xml
index 52d2976f..18b1312d 100644
--- a/aws-lambda-java-core/pom.xml
+++ b/aws-lambda-java-core/pom.xml
@@ -43,6 +43,15 @@
+
+
+ org.graalvm.sdk
+ graal-sdk
+ 21.1.0
+ provided
+
+
+
dev
diff --git a/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/graalvm/LambdaCoreGraalVMFeature.java b/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/graalvm/LambdaCoreGraalVMFeature.java
new file mode 100644
index 00000000..1ee8fb9b
--- /dev/null
+++ b/aws-lambda-java-core/src/main/java/com/amazonaws/services/lambda/runtime/graalvm/LambdaCoreGraalVMFeature.java
@@ -0,0 +1,59 @@
+package com.amazonaws.services.lambda.runtime.graalvm;
+
+import com.amazonaws.services.lambda.runtime.LambdaRuntime;
+import com.amazonaws.services.lambda.runtime.LambdaRuntimeInternal;
+import org.graalvm.nativeimage.hosted.Feature;
+import org.graalvm.nativeimage.hosted.RuntimeReflection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class programmatically registers classes, methods and fields
+ * to be added to an application when used with GraalVM native-image.
+ *
+ * These specific classes are registered because GraalVM can't detect
+ * them during static analysis.
+ *
+ * @see GraalVM native-image
+ */
+public class LambdaCoreGraalVMFeature implements Feature {
+
+ private static final Set classesForReflectConfig = new HashSet<>();
+
+ static {
+ classesForReflectConfig.add(LambdaRuntime.class);
+ classesForReflectConfig.add(LambdaRuntimeInternal.class);
+ }
+
+ @Override
+ public void beforeAnalysis(BeforeAnalysisAccess access) {
+ for (Class aClass : classesForReflectConfig) {
+ registerClass(aClass);
+ registerMethods(aClass);
+ registerFields(aClass);
+ }
+ }
+
+ private void registerMethods(Class> cl) {
+ for (Method method : cl.getDeclaredMethods()) {
+ RuntimeReflection.register(method);
+ }
+ }
+
+ private void registerFields(Class> cl) {
+ for (Field field : cl.getDeclaredFields()) {
+ RuntimeReflection.register(field);
+ }
+ }
+
+ private void registerClass(Class> cl) {
+ RuntimeReflection.register(cl);
+ for (Constructor> constructor : cl.getDeclaredConstructors()) {
+ RuntimeReflection.register(constructor);
+ }
+ }
+}
diff --git a/aws-lambda-java-core/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-core/native-image.properties b/aws-lambda-java-core/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-core/native-image.properties
new file mode 100644
index 00000000..184ca275
--- /dev/null
+++ b/aws-lambda-java-core/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-core/native-image.properties
@@ -0,0 +1 @@
+Args = --features=com.amazonaws.services.lambda.runtime.graalvm.LambdaCoreGraalVMFeature
\ No newline at end of file
diff --git a/aws-lambda-java-core/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-core/reflect-config.json b/aws-lambda-java-core/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-core/reflect-config.json
new file mode 100644
index 00000000..29ac805b
--- /dev/null
+++ b/aws-lambda-java-core/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-core/reflect-config.json
@@ -0,0 +1,13 @@
+[
+{
+ "name":"com.amazonaws.services.lambda.runtime.LambdaRuntime",
+ "methods":[{"name":"","parameterTypes":[] }],
+ "fields":[{"name":"logger"}],
+ "allPublicMethods":true
+},
+{
+ "name":"com.amazonaws.services.lambda.runtime.LambdaRuntimeInternal",
+ "methods":[{"name":"","parameterTypes":[] }],
+ "allPublicMethods":true
+}
+]
diff --git a/aws-lambda-java-events/pom.xml b/aws-lambda-java-events/pom.xml
index cde3d77c..4f346294 100644
--- a/aws-lambda-java-events/pom.xml
+++ b/aws-lambda-java-events/pom.xml
@@ -50,6 +50,13 @@
2.6
+
+ org.graalvm.sdk
+ graal-sdk
+ 21.1.0
+ provided
+
+
org.junit.jupiter
junit-jupiter-engine
@@ -68,6 +75,12 @@
2.22.0
test
+
+ io.github.classgraph
+ classgraph
+ 4.8.110
+ test
+
org.projectlombok
diff --git a/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/graalvm/LambdaEventsGraalVMFeature.java b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/graalvm/LambdaEventsGraalVMFeature.java
new file mode 100644
index 00000000..57864015
--- /dev/null
+++ b/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/graalvm/LambdaEventsGraalVMFeature.java
@@ -0,0 +1,107 @@
+package com.amazonaws.services.lambda.runtime.graalvm;
+
+import org.graalvm.nativeimage.hosted.Feature;
+import org.graalvm.nativeimage.hosted.RuntimeReflection;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * The aws-lambda-java-events library supports GraalVM by containing a reflect-config.json file. This is located
+ * src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-events/reflect-config.json
+ *
+ * This config is used by the GraalVM native-image tool in order to load the required classes and methods into the
+ * native binary it creates.
+ *
+ * Any event or response class added to this library needs to be added to this config file.
+ *
+ * This implementation of Feature does that by iterating through the events package and registering
+ * them for runtime reflection.
+ */
+public class LambdaEventsGraalVMFeature implements Feature {
+
+ public static final String EVENTS_PACKAGE_NAME = "com.amazonaws.services.lambda.runtime.events";
+
+ public static List> getClasses(String packageName)
+ throws ClassNotFoundException, IOException {
+ ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
+ assert classLoader != null;
+ String path = packageName.replace('.', '/');
+ Enumeration resources = classLoader.getResources(path);
+ List dirs = new ArrayList<>();
+ while (resources.hasMoreElements()) {
+ URL resource = resources.nextElement();
+ dirs.add(new File(resource.getFile()));
+ }
+ ArrayList> classes = new ArrayList<>();
+ for (File directory : dirs) {
+ classes.addAll(findClasses(directory, packageName));
+ }
+ return classes;
+ }
+
+ private static List> findClasses(File directory, String packageName) throws ClassNotFoundException {
+ List> classes = new ArrayList<>();
+ if (!directory.exists()) {
+ return classes;
+ }
+ File[] files = directory.listFiles();
+ if(files == null){
+ return classes;
+ }
+ for (File file : files) {
+ String fileName = file.getName();
+ if (file.isDirectory()) {
+ assert !fileName.contains(".");
+ classes.addAll(findClasses(file, packageName + "." + fileName));
+ } else if (fileName.endsWith(".class")) {
+ classes.add(Class.forName(packageName + '.' + fileName.substring(0, fileName.length() - ".class".length())));
+ }
+ }
+ return classes;
+ }
+
+ @Override
+ public void beforeAnalysis(BeforeAnalysisAccess access) {
+ try {
+ List> classes = getClasses(EVENTS_PACKAGE_NAME);
+ for (Class> cl : classes) {
+ System.out.println("Registering class:"+cl.getName());
+ registerClass(cl);
+ registerMethods(cl);
+ registerFields(cl);
+ }
+ } catch (ClassNotFoundException | IOException e) {
+ e.printStackTrace();
+ System.err.println("Failed to automatically load classes from "+ LambdaEventsGraalVMFeature.class.getName());
+ System.exit(1);
+ }
+ }
+
+ private void registerMethods(Class> cl) {
+ for (Method method : cl.getDeclaredMethods()) {
+ RuntimeReflection.register(method);
+ }
+ }
+
+ private void registerFields(Class> cl) {
+ for (Field field : cl.getDeclaredFields()) {
+ RuntimeReflection.register(field);
+ }
+ }
+
+ private void registerClass(Class> cl) {
+ RuntimeReflection.register(cl);
+ for (Constructor> constructor : cl.getDeclaredConstructors()) {
+ RuntimeReflection.register(constructor);
+ }
+ System.out.printf("\tAdding constructors for %s%n", cl.getName());
+ }
+}
\ No newline at end of file
diff --git a/aws-lambda-java-events/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-events/native-image.properties b/aws-lambda-java-events/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-events/native-image.properties
new file mode 100644
index 00000000..e8625811
--- /dev/null
+++ b/aws-lambda-java-events/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-events/native-image.properties
@@ -0,0 +1,3 @@
+Args = --enable-all-security-services \
+--enable-url-protocols=http,https \
+--features=com.amazonaws.services.lambda.runtime.graalvm.LambdaEventsGraalVMFeature
diff --git a/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/graalvm/LambdaEventsGraalVMFeatureTest.java b/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/graalvm/LambdaEventsGraalVMFeatureTest.java
new file mode 100644
index 00000000..8b4b281b
--- /dev/null
+++ b/aws-lambda-java-events/src/test/java/com/amazonaws/services/lambda/runtime/events/graalvm/LambdaEventsGraalVMFeatureTest.java
@@ -0,0 +1,43 @@
+package com.amazonaws.services.lambda.runtime.events.graalvm;
+
+import com.amazonaws.services.lambda.runtime.graalvm.LambdaEventsGraalVMFeature;
+import io.github.classgraph.ClassGraph;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.DynamicTest;
+import org.junit.jupiter.api.TestFactory;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.stream.Stream;
+
+import static com.amazonaws.services.lambda.runtime.graalvm.LambdaEventsGraalVMFeature.EVENTS_PACKAGE_NAME;
+
+/**
+ * The aws-lambda-java-events library supports GraalVM by containing a reflect-config.json file. This is located
+ * src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-events/reflect-config.json
+ *
+ * This config is used by the GraalVM native-image tool in order to load the required classes and methods into the
+ * native binary it creates.
+ *
+ * Any event or response class added to this library needs to be added to this config file.
+ *
+ * This test asserts that all the classes are included.
+ */
+public class LambdaEventsGraalVMFeatureTest {
+
+ @TestFactory
+ public Stream testEventClassesAreFound() throws IOException, ClassNotFoundException {
+
+ Set> eventClassNames = new HashSet<>(LambdaEventsGraalVMFeature.getClasses(EVENTS_PACKAGE_NAME));
+
+ return new ClassGraph()
+ .enableClassInfo()
+ .acceptPackages(EVENTS_PACKAGE_NAME)
+ .scan().getAllClasses().stream()
+ .map(classInfo -> DynamicTest.dynamicTest("Test " + classInfo.getSimpleName(), () -> {
+ Class> eventClass = classInfo.loadClass();
+ Assertions.assertTrue(eventClassNames.contains(eventClass));
+ }));
+ }
+}
\ No newline at end of file
diff --git a/aws-lambda-java-runtime-interface-client/.gitignore b/aws-lambda-java-runtime-interface-client/.gitignore
index 73a7f328..9d69fcb7 100644
--- a/aws-lambda-java-runtime-interface-client/.gitignore
+++ b/aws-lambda-java-runtime-interface-client/.gitignore
@@ -1 +1,2 @@
compile-flags.txt
+codebuild.*
diff --git a/aws-lambda-java-runtime-interface-client/Makefile b/aws-lambda-java-runtime-interface-client/Makefile
index 6d23db6d..585de89e 100644
--- a/aws-lambda-java-runtime-interface-client/Makefile
+++ b/aws-lambda-java-runtime-interface-client/Makefile
@@ -5,7 +5,7 @@ target:
.PHONY: test
test:
- mvn test
+ mvn test -q
.PHONY: setup-codebuild-agent
setup-codebuild-agent:
@@ -16,6 +16,11 @@ test-smoke: setup-codebuild-agent
CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_one.sh test/integration/codebuild/buildspec.os.alpine.yml alpine 3.12 corretto11
CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_one.sh test/integration/codebuild/buildspec.os.amazoncorretto.yml amazoncorretto amazoncorretto 11
+.PHONY: test-graalvm
+test-graalvm:
+ docker build --progress=plain -t codebuild-agent - < test/integration/codebuild-local/Dockerfile.graalvm-agent
+ CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_one.sh test/integration/codebuild-graalvm/buildspec.os.amazoncorretto.yml amazoncorretto amazoncorretto 11
+
.PHONY: test-integ
test-integ: setup-codebuild-agent
CODEBUILD_IMAGE_TAG=codebuild-agent test/integration/codebuild-local/test_all.sh test/integration/codebuild
@@ -30,7 +35,7 @@ pr: test test-smoke
.PHONY: build
build:
- mvn clean install
+ mvn clean install -q
define HELP_MESSAGE
diff --git a/aws-lambda-java-runtime-interface-client/README.md b/aws-lambda-java-runtime-interface-client/README.md
index d8771d2a..d01e006c 100644
--- a/aws-lambda-java-runtime-interface-client/README.md
+++ b/aws-lambda-java-runtime-interface-client/README.md
@@ -2,12 +2,12 @@
We have open-sourced a set of software packages, Runtime Interface Clients (RIC), that implement the Lambda
[Runtime API](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-api.html), allowing you to seamlessly extend your preferred
- base images to be Lambda compatible.
+ base images to be Lambda compatible or to implement your own custom Lambda runtime.
The Lambda Runtime Interface Client is a lightweight interface that allows your runtime to receive requests from and send requests to the Lambda service.
-You can include this package in your preferred base image to make that base image Lambda compatible.
+## Usage 1: Deploy your Lambda as a Container Image without native compilation
-## Usage
+You can include this package in your preferred base image to make that base image Lambda compatible.
### Creating a Docker Image for Lambda with the Runtime Interface Client
@@ -70,7 +70,7 @@ pom.xml
com.amazonaws
aws-lambda-java-runtime-interface-client
- 1.1.0
+ 1.0.0
@@ -151,6 +151,222 @@ DOCKERHUB_PASSWORD=
```
Recommended way is to set the Docker Hub credentials in CodeBuild job by retrieving them from AWS Secrets Manager.
+## Usage 2: Deploy your Lambda with Native Compilation
+
+You can include this package as a dependency to build your Custom Runtime or to run your Lambda as a Container without any Java Runtime.
+
+The idea here is to compile natively your java bytecode with [GraalVM](https://www.graalvm.org) [native-image](https://www.graalvm.org/reference-manual/native-image/) to a linux executable file.
+In order to ease this native compilation of the Java Runtime Interface Client, the Java RIC jar artifact is now including special configuration files for GraalVM native-image.
+
+Note: In this example the docker image provided may be used
+* For cross compiling only to linux x86-64 and extract the Custom Runtime zip to deploy
+* For deploying your Lambda as a Container Image
+* For local testing of your Container Image or your native executable.
+
+### Example: hello-lambda-native project
+
+Let's take the same Lambda as before:
+
+src/main/java/example/App.java
+```java
+package example;
+
+public class App {
+ public static String sayHello() {
+ return "Hello λ!";
+ }
+}
+```
+
+This is the needed configuration for native-image for finding the Lambda code:
+
+src/main/resources/META-INF/native-image/reflect-config.json
+```json
+[
+{
+ "name":"example.App",
+ "allPublicMethods":true
+}
+]
+```
+
+When building a Custom Runtime you need a zip archive containing at root a file named bootstrap that will be the entry point for running your Lambda. In a Container, the same bootstrap file is used as ENTRYPOINT. And finally, it contains also the logic to identify the case of local testing:
+
+bootstrap
+```bash
+#!/bin/sh
+if [ -z "${AWS_LAMBDA_RUNTIME_API}" ]; then
+ exec /usr/bin/aws-lambda-rie ./func $1
+else
+ set -euo pipefail
+ exec ./func $_HANDLER
+fi
+```
+
+The Dockerfile is slightly more complex to support the three use cases described above:
+
+Dockerfile
+```dockerfile
+FROM amazonlinux:2 as base
+
+FROM base as build
+ENV LANG=en_US.UTF-8
+RUN yum update -y && yum install -y gcc gcc-c++ zlib-devel zip tar gzip && yum clean all
+RUN curl -4 -L https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-20.3.0/graalvm-ce-java11-linux-amd64-20.3.0.tar.gz -o /tmp/graalvm.tar.gz \
+ && tar -zxf /tmp/graalvm.tar.gz -C /tmp \
+ && mv /tmp/graalvm-ce-java11-20.3.0 /usr/lib/graalvm \
+ && rm -rf /tmp/*
+RUN /usr/lib/graalvm/bin/gu install native-image
+ENV PATH=/usr/lib/graalvm/bin:${PATH}
+ENV JAVA_HOME=/usr/lib/graalvm
+RUN yum install -y maven
+
+# compile the function
+WORKDIR /home/app
+ADD . .
+RUN mvn package
+
+COPY bootstrap /home/app/
+# (Optional) Add Lambda Runtime Interface Emulator and use a script in the ENTRYPOINT for simpler local runs
+ADD https://github.com/aws/aws-lambda-runtime-interface-emulator/releases/latest/download/aws-lambda-rie /home/app/aws-lambda-rie
+RUN native-image -jar target/hello-lambda-native-1.0-SNAPSHOT.jar -H:Name=func --no-fallback
+RUN yum install -y zip && yum clean all
+RUN chmod 755 aws-lambda-rie
+RUN chmod 755 bootstrap
+RUN chmod 755 func
+RUN zip -j function.zip bootstrap func
+
+FROM base
+WORKDIR /function
+COPY --from=build /home/app/func /function/func
+COPY --from=build /home/app/bootstrap /function/bootstrap
+COPY --from=build /home/app/function.zip /function/function.zip
+COPY --from=build /home/app/aws-lambda-rie /usr/bin/aws-lambda-rie
+ENTRYPOINT [ "/function/bootstrap" ]
+CMD [ "example.App::sayHello" ]
+```
+
+pom.xml
+```xml
+
+ 4.0.0
+ example
+ hello-lambda-native
+ 1.0-SNAPSHOT
+
+
+ 11
+ 11
+ com.amazonaws.services.lambda.runtime.api.client.AWSLambda
+
+
+
+
+ com.amazonaws
+ aws-lambda-java-runtime-interface-client
+ 1.0.0
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.6.0
+
+ ${jdk.version}
+ ${release.version}
+ UTF-8
+
+
+
+
+ org.apache.maven.plugins
+ maven-dependency-plugin
+ 3.1.2
+
+
+ copy-dependencies
+ prepare-package
+
+ copy-dependencies
+
+
+
+ ${project.build.directory}/libs
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+ 3.2.0
+
+
+
+ true
+ libs/
+ ${exec.mainClass}
+
+
+
+
+
+
+
+
+
+
+```
+
+### Custom Runtime
+
+just build the image with Docker:
+
+```bash
+docker build -t hello-lambda-native:latest .
+```
+
+Then extract the Custom Runtime deployable zip bundle with this command:
+
+```bash
+docker cp $(docker create hello-lambda-native:latest):/function/function.zip .
+```
+
+### Container with native compilation
+
+just build the image with Docker:
+
+```bash
+docker build -t hello-lambda-native:latest .
+```
+
+This image can be deployed directly.
+
+### Local Testing
+
+just build the image with Docker:
+
+```bash
+docker build -t hello-lambda-native:latest .
+```
+
+Then you can run the image locally:
+
+```bash
+docker run -p 9000:8080 hello-lambda-native:latest
+```
+
+And test it from another Terminal/Console with:
+
+```bash
+curl -XPOST "http://localhost:9000/2015-03-31/functions/function/invocations" -d '{}'
+```
+
## Security
If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue.
@@ -158,4 +374,3 @@ If you discover a potential security issue in this project we ask that you notif
## License
This project is licensed under the Apache-2.0 License.
-
diff --git a/aws-lambda-java-runtime-interface-client/pom.xml b/aws-lambda-java-runtime-interface-client/pom.xml
index 68f2e364..3063698a 100644
--- a/aws-lambda-java-runtime-interface-client/pom.xml
+++ b/aws-lambda-java-runtime-interface-client/pom.xml
@@ -39,7 +39,7 @@
com.amazonaws
aws-lambda-java-core
- 1.2.0
+ 1.2.1
com.amazonaws
@@ -47,6 +47,13 @@
1.0.0
+
+ org.graalvm.sdk
+ graal-sdk
+ 21.1.0
+ provided
+
+
org.junit.jupiter
junit-jupiter-engine
diff --git a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/graalvm/LambdaRuntimeGraalVMFeature.java b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/graalvm/LambdaRuntimeGraalVMFeature.java
new file mode 100644
index 00000000..1edf9b0e
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/graalvm/LambdaRuntimeGraalVMFeature.java
@@ -0,0 +1,57 @@
+package com.amazonaws.services.lambda.runtime.api.client.graalvm;
+
+import com.amazonaws.services.lambda.runtime.api.client.runtimeapi.InvocationRequest;
+import org.graalvm.nativeimage.hosted.Feature;
+import org.graalvm.nativeimage.hosted.RuntimeReflection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class programmatically registers classes, methods and fields
+ * to be added to an application when used with GraalVM native-image.
+ *
+ * These specific classes are registered because GraalVM can't detect
+ * them during static analysis.
+ *
+ * @see GraalVM native-image
+ */
+public class LambdaRuntimeGraalVMFeature implements Feature {
+
+ private static final Set classesForReflectConfig = new HashSet<>();
+
+ static {
+ classesForReflectConfig.add(InvocationRequest.class);
+ }
+
+ @Override
+ public void beforeAnalysis(BeforeAnalysisAccess access) {
+ for (Class aClass : classesForReflectConfig) {
+ registerClass(aClass);
+ registerMethods(aClass);
+ registerFields(aClass);
+ }
+ }
+
+ private void registerMethods(Class> cl) {
+ for (Method method : cl.getDeclaredMethods()) {
+ RuntimeReflection.register(method);
+ }
+ }
+
+ private void registerFields(Class> cl) {
+ for (Field field : cl.getDeclaredFields()) {
+ RuntimeReflection.register(field);
+ }
+ }
+
+ private void registerClass(Class> cl) {
+ RuntimeReflection.register(cl);
+ for (Constructor> constructor : cl.getDeclaredConstructors()) {
+ RuntimeReflection.register(constructor);
+ }
+ }
+}
diff --git a/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/jni-config.json b/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/jni-config.json
new file mode 100644
index 00000000..e6c7da3c
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/jni-config.json
@@ -0,0 +1,11 @@
+[
+{
+ "name":"com.amazonaws.services.lambda.runtime.api.client.runtimeapi.LambdaRuntimeClientException",
+ "methods":[{"name":"","parameterTypes":["java.lang.String","int"] }]
+},
+{
+ "name":"com.amazonaws.services.lambda.runtime.api.client.runtimeapi.InvocationRequest",
+ "fields":[{"name":"id"}, {"name":"invokedFunctionArn"}, {"name":"deadlineTimeInMs"}, {"name":"xrayTraceId"}, {"name":"clientContext"}, {"name":"cognitoIdentity"}, {"name":"content"}],
+ "allPublicMethods":true
+}
+]
diff --git a/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/native-image.properties b/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/native-image.properties
new file mode 100644
index 00000000..c1ebbe99
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/native-image.properties
@@ -0,0 +1,6 @@
+Args = --initialize-at-build-time=jdk.xml.internal.SecuritySupport \
+-H:ReflectionConfigurationResources=${.}/reflect-config.json \
+-H:JNIConfigurationResources=${.}/jni-config.json \
+-H:ResourceConfigurationResources=${.}/resource-config.json \
+--features=com.amazonaws.services.lambda.runtime.api.client.graalvm.LambdaRuntimeGraalVMFeature
+
diff --git a/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/reflect-config.json b/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/reflect-config.json
new file mode 100644
index 00000000..80e8c7d3
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/reflect-config.json
@@ -0,0 +1,18 @@
+[
+{
+ "name":"java.lang.Void",
+ "methods":[{"name":"","parameterTypes":[] }]
+},
+{
+ "name":"java.util.Collections$UnmodifiableMap",
+ "fields":[{"name":"m"}]
+},
+{
+ "name":"jdk.internal.module.IllegalAccessLogger",
+ "fields":[{"name":"logger"}]
+},
+{
+ "name":"sun.misc.Unsafe",
+ "fields":[{"name":"theUnsafe"}]
+}
+]
diff --git a/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/resource-config.json b/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/resource-config.json
new file mode 100644
index 00000000..18f4ba9b
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/src/main/resources/META-INF/native-image/com.amazonaws/aws-lambda-java-runtime-interface-client/resource-config.json
@@ -0,0 +1,8 @@
+{
+ "resources":{
+ "includes":[
+ {"pattern":"\\Qaws-lambda-runtime-interface-client.glibc.so\\E"},
+ {"pattern":"\\Qaws-lambda-runtime-interface-client.musl.so\\E"}
+ ]},
+ "bundles":[]
+}
diff --git a/aws-lambda-java-runtime-interface-client/test/integration/codebuild-graalvm/buildspec.os.amazoncorretto.yml b/aws-lambda-java-runtime-interface-client/test/integration/codebuild-graalvm/buildspec.os.amazoncorretto.yml
new file mode 100644
index 00000000..70491691
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/test/integration/codebuild-graalvm/buildspec.os.amazoncorretto.yml
@@ -0,0 +1,147 @@
+version: 0.2
+
+env:
+ variables:
+ OS_DISTRIBUTION: amazoncorretto
+ JAVA_BINARY_LOCATION: "/usr/bin/java"
+batch:
+ build-matrix:
+ static:
+ ignore-failure: false
+ env:
+ type: LINUX_CONTAINER
+ privileged-mode: true
+ dynamic:
+ env:
+ variables:
+ DISTRO_VERSION:
+ - "amazoncorretto"
+ RUNTIME_VERSION:
+ - "11"
+phases:
+ install:
+ commands:
+ - >
+ if [[ -z "${DOCKERHUB_USERNAME}" && -z "${DOCKERHUB_PASSWORD}" ]];
+ then
+ echo "DockerHub credentials not set as CodeBuild environment variables. Continuing without docker login."
+ else
+ echo "Performing DockerHub login . . ."
+ docker login -u $DOCKERHUB_USERNAME -p $DOCKERHUB_PASSWORD
+ fi
+ pre_build:
+ commands:
+ # Install events (dependency of serialization)
+ - (cd aws-lambda-java-events && mvn install -q)
+ # Install serialization (dependency of RIC)
+ - (cd aws-lambda-java-core && mvn install -q)
+ - (cd aws-lambda-java-serialization && mvn install -q)
+ - (cd aws-lambda-java-runtime-interface-client && mvn install -q)
+ - (cd aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler && mvn install -P native-image)
+ - export IMAGE_TAG="java-${OS_DISTRIBUTION}-${DISTRO_VERSION}:${RUNTIME_VERSION}"
+ - echo "Extracting and including Runtime Interface Emulator"
+ - SCRATCH_DIR=".scratch"
+ - mkdir "${SCRATCH_DIR}"
+ - tar -xvf aws-lambda-java-runtime-interface-client/test/integration/resources/aws-lambda-rie.tar.gz --directory "${SCRATCH_DIR}"
+ - >
+ cp "aws-lambda-java-runtime-interface-client/test/integration/docker/Dockerfile.function.graalvm" \
+ "${SCRATCH_DIR}/Dockerfile.function.graalvm.tmp"
+ - >
+ echo "COPY ${SCRATCH_DIR}/aws-lambda-rie /usr/bin/aws-lambda-rie" >> \
+ "${SCRATCH_DIR}/Dockerfile.function.graalvm.tmp"
+ - echo "Building image ${IMAGE_TAG}"
+ - >
+ docker build . \
+ -f "${SCRATCH_DIR}/Dockerfile.function.graalvm.tmp" \
+ -t "${IMAGE_TAG}" \
+ --build-arg RUNTIME_VERSION="${RUNTIME_VERSION}" \
+ --build-arg DISTRO_VERSION="${DISTRO_VERSION}"
+ build:
+ commands:
+ - set -x
+ - echo "Running Image ${IMAGE_TAG}"
+ - docker network create "${OS_DISTRIBUTION}-network"
+ - >
+ docker run \
+ --detach \
+ -e "JAVA_BINARY_LOCATION=${JAVA_BINARY_LOCATION}" \
+ --name "${OS_DISTRIBUTION}-app" \
+ --network "${OS_DISTRIBUTION}-network" \
+ --entrypoint="" \
+ "${IMAGE_TAG}" \
+ sh -c '/usr/bin/aws-lambda-rie ./hello-binary helloworld.RequestHandlerApp'
+ - sleep 2
+ - >
+ docker run \
+ --name "${OS_DISTRIBUTION}-tester" \
+ --env "TARGET=${OS_DISTRIBUTION}-app" \
+ --network "${OS_DISTRIBUTION}-network" \
+ --entrypoint="" \
+ "${IMAGE_TAG}" \
+ sh -c 'curl -X POST "http://${TARGET}:8080/2015-03-31/functions/function/invocations" -d "{}" --max-time 10'
+ - actual="$(docker logs --tail 1 "${OS_DISTRIBUTION}-tester" | xargs)"
+ - expected='success'
+ - |
+ echo "Response: ${actual}"
+ if [[ "$actual" != "$expected" ]]; then
+ echo "fail! runtime: $RUNTIME - expected output $expected - got $actual"
+ echo "---------Container Logs: ${OS_DISTRIBUTION}-app----------"
+ echo
+ docker logs "${OS_DISTRIBUTION}-app"
+ echo
+ echo "---------------------------------------------------"
+ echo "--------Container Logs: ${OS_DISTRIBUTION}-tester--------"
+ echo
+ docker logs "${OS_DISTRIBUTION}-tester"
+ echo
+ echo "---------------------------------------------------"
+ exit -1
+ fi
+ - docker stop "${OS_DISTRIBUTION}-app" || true
+ - docker rm --force "${OS_DISTRIBUTION}-app" || true
+ - docker stop "${OS_DISTRIBUTION}-tester" || true
+ - docker rm --force "${OS_DISTRIBUTION}-tester" || true
+ - >
+ docker run \
+ --detach \
+ -e "JAVA_BINARY_LOCATION=${JAVA_BINARY_LOCATION}" \
+ --name "${OS_DISTRIBUTION}-app" \
+ --network "${OS_DISTRIBUTION}-network" \
+ --entrypoint="" \
+ "${IMAGE_TAG}" \
+ sh -c '/usr/bin/aws-lambda-rie ./hello-binary helloworld.StreamHandlerApp'
+ - sleep 2
+ - >
+ docker run \
+ --name "${OS_DISTRIBUTION}-tester" \
+ --env "TARGET=${OS_DISTRIBUTION}-app" \
+ --network "${OS_DISTRIBUTION}-network" \
+ --entrypoint="" \
+ "${IMAGE_TAG}" \
+ sh -c 'curl -X POST "http://${TARGET}:8080/2015-03-31/functions/function/invocations" -d "{}" --max-time 10'
+ - actual="$(docker logs --tail 1 "${OS_DISTRIBUTION}-tester" | xargs)"
+ - expected='success'
+ - |
+ echo "Response: ${actual}"
+ if [[ "$actual" != "$expected" ]]; then
+ echo "fail! runtime: $RUNTIME - expected output $expected - got $actual"
+ echo "---------Container Logs: ${OS_DISTRIBUTION}-app----------"
+ echo
+ docker logs "${OS_DISTRIBUTION}-app"
+ echo
+ echo "---------------------------------------------------"
+ echo "--------Container Logs: ${OS_DISTRIBUTION}-tester--------"
+ echo
+ docker logs "${OS_DISTRIBUTION}-tester"
+ echo
+ echo "---------------------------------------------------"
+ exit -1
+ fi
+
+ finally:
+ - echo "Cleaning up..."
+ - docker stop "${OS_DISTRIBUTION}-app" || true
+ - docker rm --force "${OS_DISTRIBUTION}-app" || true
+ - docker stop "${OS_DISTRIBUTION}-tester" || true
+ - docker rm --force "${OS_DISTRIBUTION}-tester" || true
+ - docker network rm "${OS_DISTRIBUTION}-network" || true
\ No newline at end of file
diff --git a/aws-lambda-java-runtime-interface-client/test/integration/codebuild-local/Dockerfile.graalvm-agent b/aws-lambda-java-runtime-interface-client/test/integration/codebuild-local/Dockerfile.graalvm-agent
new file mode 100644
index 00000000..37aa024b
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/test/integration/codebuild-local/Dockerfile.graalvm-agent
@@ -0,0 +1,36 @@
+FROM amazoncorretto:11
+
+RUN amazon-linux-extras enable docker && yum clean metadata
+RUN yum -y update \
+ && yum install -y docker tar gzip bzip2-devel ed gcc gcc-c++ gcc-gfortran \
+ less libcurl-devel openssl openssl-devel readline-devel xz-devel \
+ zlib-devel glibc-static libcxx libcxx-devel llvm-toolset-7 zlib-static \
+ && rm -rf /var/cache/yum
+
+
+ENV GRAAL_VERSION 21.1.0
+ENV GRAAL_FOLDERNAME graalvm-ce-java11-${GRAAL_VERSION}
+ENV GRAAL_FILENAME graalvm-ce-java11-linux-amd64-${GRAAL_VERSION}.tar.gz
+RUN curl -4 -L https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-${GRAAL_VERSION}/${GRAAL_FILENAME} | tar -xvz
+RUN mv $GRAAL_FOLDERNAME /usr/lib/graalvm
+RUN rm -rf $GRAAL_FOLDERNAME
+
+# Graal maven plugin requires Maven 3.3.x
+ENV MVN_VERSION 3.6.3
+ENV MVN_FOLDERNAME apache-maven-${MVN_VERSION}
+ENV MVN_FILENAME apache-maven-${MVN_VERSION}-bin.tar.gz
+RUN curl -4 -L https://mirrors.ukfast.co.uk/sites/ftp.apache.org/maven/maven-3/${MVN_VERSION}/binaries/${MVN_FILENAME} | tar -xvz
+RUN mv $MVN_FOLDERNAME /usr/lib/maven
+RUN rm -rf $MVN_FOLDERNAME
+
+VOLUME /project
+WORKDIR /project
+
+RUN /usr/lib/graalvm/bin/gu install native-image
+RUN ln -s /usr/lib/graalvm/bin/native-image /usr/bin/native-image
+RUN ln -s /usr/lib/maven/bin/mvn /usr/bin/mvn
+
+ENV JAVA_HOME /usr/lib/graalvm
+
+ENTRYPOINT ["sh"]
+
diff --git a/aws-lambda-java-runtime-interface-client/test/integration/docker/Dockerfile.function.graalvm b/aws-lambda-java-runtime-interface-client/test/integration/docker/Dockerfile.function.graalvm
new file mode 100644
index 00000000..2df60167
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/test/integration/docker/Dockerfile.function.graalvm
@@ -0,0 +1,9 @@
+ARG RUNTIME_VERSION
+
+FROM amazoncorretto:${RUNTIME_VERSION}
+
+ADD aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/target/hello-binary .
+
+ENTRYPOINT ["hello-binary", "helloworld.RequestHandlerApp"]
+
+CMD ["helloworld.RequestHandlerApp"]
diff --git a/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/pom.xml b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/pom.xml
new file mode 100644
index 00000000..0f4f6296
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/pom.xml
@@ -0,0 +1,113 @@
+
+ 4.0.0
+ helloworld
+ HelloWorld
+ 1.0
+ jar
+ A sample Hello World.
+
+ 1.8
+ 1.8
+
+
+
+
+ com.amazonaws
+ aws-lambda-java-runtime-interface-client
+ 1.1.0
+
+
+ com.amazonaws
+ aws-lambda-java-events
+ 3.9.0
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.1.1
+
+
+
+
+ package
+
+ shade
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-jar-plugin
+
+
+
+ com.amazonaws.services.lambda.runtime.api.client.AWSLambda
+
+
+
+
+
+
+
+
+
+ native-image
+
+
+
+ org.graalvm.nativeimage
+ native-image-maven-plugin
+ 21.1.0
+
+
+
+ native-image
+
+
+
+
+ hello-binary
+ com.amazonaws.services.lambda.runtime.api.client.AWSLambda
+
+ --verbose
+ --no-fallback
+ --initialize-at-build-time=org.slf4j
+ --enable-url-protocols=http
+ -H:+AllowIncompleteClasspath
+
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+ 3.3.0
+
+
+ zip-assembly
+ package
+
+ single
+
+
+ function
+
+ src/assembly/zip.xml
+
+ false
+ false
+
+
+
+
+
+
+
+
+
+
diff --git a/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/assembly/zip.xml b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/assembly/zip.xml
new file mode 100644
index 00000000..acb1fa47
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/assembly/zip.xml
@@ -0,0 +1,23 @@
+
+ lambda-package
+
+ zip
+
+ false
+
+
+ ${project.build.directory}${file.separator}hello-binary
+ ${file.separator}
+ hello-binary
+ 777
+
+
+ src${file.separator}main${file.separator}config${file.separator}bootstrap
+ ${file.separator}
+ bootstrap
+ 777
+
+
+
\ No newline at end of file
diff --git a/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/config/bootstrap b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/config/bootstrap
new file mode 100644
index 00000000..76cc8f83
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/config/bootstrap
@@ -0,0 +1,3 @@
+#!/usr/bin/env bash
+
+./hello-binary $_HANDLER
\ No newline at end of file
diff --git a/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/java/helloworld/RequestHandlerApp.java b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/java/helloworld/RequestHandlerApp.java
new file mode 100644
index 00000000..db521bd8
--- /dev/null
+++ b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/java/helloworld/RequestHandlerApp.java
@@ -0,0 +1,25 @@
+package helloworld;
+
+import com.amazonaws.services.lambda.runtime.Context;
+import com.amazonaws.services.lambda.runtime.RequestHandler;
+
+import java.util.Map;
+
+/**
+ * Handler for requests to Lambda function.
+ */
+public class RequestHandlerApp implements RequestHandler
+
+ org.graalvm.sdk
+ graal-sdk
+ 21.1.0
+ provided
+
+
org.junit.jupiter
junit-jupiter-engine
diff --git a/aws-lambda-java-serialization/src/main/java/com/amazonaws/services/lambda/runtime/serialization/graalvm/LambdaSerializationGraalVMFeature.java b/aws-lambda-java-serialization/src/main/java/com/amazonaws/services/lambda/runtime/serialization/graalvm/LambdaSerializationGraalVMFeature.java
new file mode 100644
index 00000000..3cc3b004
--- /dev/null
+++ b/aws-lambda-java-serialization/src/main/java/com/amazonaws/services/lambda/runtime/serialization/graalvm/LambdaSerializationGraalVMFeature.java
@@ -0,0 +1,64 @@
+package com.amazonaws.services.lambda.runtime.serialization.graalvm;
+
+import com.fasterxml.jackson.databind.deser.Deserializers;
+import com.fasterxml.jackson.databind.ext.Java7Handlers;
+import com.fasterxml.jackson.databind.ext.Java7HandlersImpl;
+import com.fasterxml.jackson.databind.ext.Java7SupportImpl;
+import com.fasterxml.jackson.databind.ser.Serializers;
+import org.graalvm.nativeimage.hosted.Feature;
+import org.graalvm.nativeimage.hosted.RuntimeReflection;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * This class programmatically registers classes, methods and fields
+ * to be added to an application when used with GraalVM native-image.
+ *
+ * These specific classes are registered because GraalVM can't detect
+ * them during static analysis.
+ *
+ * @see GraalVM native-image
+ */
+public class LambdaSerializationGraalVMFeature implements Feature {
+
+ private static final Set classesForReflectConfig = new HashSet<>();
+
+ static {
+ classesForReflectConfig.add(Deserializers.class);
+ classesForReflectConfig.add(Serializers.class);
+ classesForReflectConfig.add(Java7SupportImpl.class);
+ classesForReflectConfig.add(Java7HandlersImpl.class);
+ }
+
+ @Override
+ public void beforeAnalysis(BeforeAnalysisAccess access) {
+ for (Class aClass : classesForReflectConfig) {
+ registerClass(aClass);
+ registerMethods(aClass);
+ registerFields(aClass);
+ }
+ }
+
+ private void registerMethods(Class> cl) {
+ for (Method method : cl.getDeclaredMethods()) {
+ RuntimeReflection.register(method);
+ }
+ }
+
+ private void registerFields(Class> cl) {
+ for (Field field : cl.getDeclaredFields()) {
+ RuntimeReflection.register(field);
+ }
+ }
+
+ private void registerClass(Class> cl) {
+ RuntimeReflection.register(cl);
+ for (Constructor> constructor : cl.getDeclaredConstructors()) {
+ RuntimeReflection.register(constructor);
+ }
+ }
+}
diff --git a/aws-lambda-java-serialization/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-serialization/native-image.properties b/aws-lambda-java-serialization/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-serialization/native-image.properties
new file mode 100644
index 00000000..3ed2e432
--- /dev/null
+++ b/aws-lambda-java-serialization/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-serialization/native-image.properties
@@ -0,0 +1,2 @@
+Args = -H:ReflectionConfigurationResources=${.}/reflect-config.json \
+--features=com.amazonaws.services.lambda.runtime.serialization.graalvm.LambdaSerializationGraalVMFeature
\ No newline at end of file
diff --git a/aws-lambda-java-serialization/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-serialization/reflect-config.json b/aws-lambda-java-serialization/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-serialization/reflect-config.json
new file mode 100644
index 00000000..07a1f730
--- /dev/null
+++ b/aws-lambda-java-serialization/src/main/resources/META-INF/native-image/com/amazonaws/aws-lambda-java-serialization/reflect-config.json
@@ -0,0 +1,22 @@
+[
+ {
+ "name":"com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.deser.Deserializers[]"
+ },
+ {
+ "name":"com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ext.Java7HandlersImpl",
+ "methods":[{"name":"","parameterTypes":[] }]
+ },
+ {
+ "name":"com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ext.Java7SupportImpl",
+ "methods":[{"name":"","parameterTypes":[] }]
+ },
+ {
+ "name":"com.amazonaws.lambda.thirdparty.com.fasterxml.jackson.databind.ser.Serializers[]"
+ },
+ {
+ "name": "org.joda.time.DateTime",
+ "allDeclaredFields": true,
+ "allDeclaredMethods": true,
+ "allDeclaredConstructors": true
+ }
+]