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, String>{ + @Override + public String handleRequest(Map event, Context context) + { + try{ + //test to make sure all events are available + Class.forName("com.amazonaws.services.lambda.runtime.events.CloudFrontEvent"); + }catch(Exception e){ + e.printStackTrace(); + return "error"; + } + + return "success"; + } +} diff --git a/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/java/helloworld/StreamHandlerApp.java b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/java/helloworld/StreamHandlerApp.java new file mode 100644 index 00000000..f8e00906 --- /dev/null +++ b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/java/helloworld/StreamHandlerApp.java @@ -0,0 +1,33 @@ +package helloworld; + +import com.amazonaws.services.lambda.runtime.Context; +import com.amazonaws.services.lambda.runtime.RequestHandler; +import com.amazonaws.services.lambda.runtime.RequestStreamHandler; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.charset.StandardCharsets; +import java.util.Map; + +/** + * Handler for requests to Lambda function. + */ +public class StreamHandlerApp implements RequestStreamHandler { + + @Override + public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { + try{ + //test to make sure all events are available + Class.forName("com.amazonaws.services.lambda.runtime.events.CloudFrontEvent"); + }catch(Exception e){ + e.printStackTrace(); + outputStream.write("error".getBytes(StandardCharsets.UTF_8)); + outputStream.flush(); + return; + } + + outputStream.write("success".getBytes(StandardCharsets.UTF_8)); + outputStream.flush(); + } +} diff --git a/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/resources/META-INF/native-image/native-image.properties b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/resources/META-INF/native-image/native-image.properties new file mode 100644 index 00000000..cd81623c --- /dev/null +++ b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/resources/META-INF/native-image/native-image.properties @@ -0,0 +1,3 @@ +Args = --enable-all-security-services \ +--enable-url-protocols=http,https \ +-H:ReflectionConfigurationResources=${.}/reflect-config.json \ No newline at end of file diff --git a/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/resources/META-INF/native-image/reflect-config.json b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/resources/META-INF/native-image/reflect-config.json new file mode 100644 index 00000000..375c6c10 --- /dev/null +++ b/aws-lambda-java-runtime-interface-client/test/integration/graalvm-test-handler/src/main/resources/META-INF/native-image/reflect-config.json @@ -0,0 +1,20 @@ +[ + { + "name": "helloworld.RequestHandlerApp", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + }, + { + "name": "helloworld.StreamHandlerApp", + "allDeclaredConstructors": true, + "allPublicConstructors": true, + "allDeclaredMethods": true, + "allPublicMethods": true, + "allDeclaredClasses": true, + "allPublicClasses": true + } +] \ No newline at end of file diff --git a/aws-lambda-java-serialization/pom.xml b/aws-lambda-java-serialization/pom.xml index a0073e6e..8abb0a6e 100644 --- a/aws-lambda-java-serialization/pom.xml +++ b/aws-lambda-java-serialization/pom.xml @@ -52,6 +52,13 @@ 20160810 + + 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 + } +]