Skip to content

feat(v2): GraalVM support for parameters module #1824

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 13 commits into from
May 26, 2025
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,14 @@

<modules>
<module>powertools-examples-core-utilities/sam</module>
<module>powertools-examples-core-utilities/sam-graalvm</module>
<module>powertools-examples-core-utilities/cdk/app</module>
<module>powertools-examples-core-utilities/cdk/infra</module>
<module>powertools-examples-core-utilities/serverless</module>
<module>powertools-examples-core-utilities/terraform</module>
<module>powertools-examples-idempotency</module>
<module>powertools-examples-parameters</module>
<module>powertools-examples-parameters/sam</module>
<module>powertools-examples-parameters/sam-graalvm</module>
<module>powertools-examples-serialization</module>
<module>powertools-examples-batch</module>
<module>powertools-examples-validation</module>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<name>Powertools for AWS Lambda (Java) - Examples - Core Utilities (logging, tracing, metrics) with SAM</name>
<groupId>software.amazon.lambda.examples</groupId>
<version>2.0.0-SNAPSHOT</version>
<artifactId>powertools-examples-core-utilitiessam-graalvm</artifactId>
<artifactId>powertools-examples-core-utilities-sam-graalvm</artifactId>
<packaging>jar</packaging>

<properties>
Expand Down
14 changes: 14 additions & 0 deletions examples/powertools-examples-parameters/sam-graalvm/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#Use the official AWS SAM base image for Java 21
FROM public.ecr.aws/sam/build-java21:latest

#Install GraalVM dependencies
RUN curl -4 -L curl https://download.oracle.com/graalvm/21/latest/graalvm-jdk-21_linux-x64_bin.tar.gz | tar -xvz
RUN mv graalvm-jdk-21.* /usr/lib/graalvm

#Make native image and mvn available on CLI
RUN ln -s /usr/lib/graalvm/bin/native-image /usr/bin/native-image
RUN ln -s /usr/lib/maven/bin/mvn /usr/bin/mvn

#Set GraalVM as default
ENV JAVA_HOME=/usr/lib/graalvm
ENV PATH=/usr/lib/graalvm/bin:$PATH
6 changes: 6 additions & 0 deletions examples/powertools-examples-parameters/sam-graalvm/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
build-ParametersFunction:

chmod +x target/hello-world
cp target/hello-world $(ARTIFACTS_DIR) # (ARTIFACTS_DIR --> https://github.com/aws/aws-lambda-builders/blob/develop/aws_lambda_builders/workflows/custom_make/DESIGN.md#implementation)
chmod +x src/main/config/bootstrap
cp src/main/config/bootstrap $(ARTIFACTS_DIR)
80 changes: 80 additions & 0 deletions examples/powertools-examples-parameters/sam-graalvm/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Powertools for AWS Lambda (Java) - Parameters Example with SAM on GraalVM

This project contains an example of Lambda function using the parameters module of Powertools for AWS Lambda (Java). For more information on this module, please refer to the [documentation](https://docs.powertools.aws.dev/lambda-java/utilities/parameters/).

The example uses the [SSM Parameter Store](https://docs.powertools.aws.dev/lambda/java/utilities/parameters/#ssm-parameter-store)
and the [Secrets Manager](https://docs.powertools.aws.dev/lambda/java/utilities/parameters/#secrets-manager) to inject
runtime parameters into the application.
Have a look at [ParametersFunction.java](src/main/java/org/demo/parameters/ParametersFunction.java) for the full details.

## Configuration

- SAM uses [template.yaml](template.yaml) to define the application's AWS resources.
This file defines the Lambda function to be deployed as well as API Gateway for it.

- Set the environment to use GraalVM

```shell
export JAVA_HOME=<path to GraalVM>
```

## Build the sample application

- Build the Docker image that will be used as the environment for SAM build:

```shell
docker build --platform linux/amd64 . -t powertools-examples-parameters-sam-graalvm
```

- Build the SAM project using the docker image

```shell
sam build --use-container --build-image powertools-examples-parameters-sam-graalvm
```

#### [Optional] Building with -SNAPSHOT versions of PowerTools

- If you are testing the example with a -SNAPSHOT version of PowerTools, the maven build inside the docker image will fail. This is because the -SNAPSHOT version of the PowerTools library that you are working on is still not available in maven central/snapshot repository.
To get around this, follow these steps:
- Create the native image using the `docker` command below on your development machine. The native image is created in the `target` directory.
- `` docker run --platform linux/amd64 -it -v `pwd`:`pwd` -w `pwd` -v ~/.m2:/root/.m2 powertools-examples-parameters-sam-graalvm mvn clean -Pnative-image package -DskipTests ``
- Edit the [`Makefile`](Makefile) remove this line
- `mvn clean package -P native-image`
- Build the SAM project using the docker image
- `sam build --use-container --build-image powertools-examples-parameters-sam-graalvm`

## Deploy the sample application

- SAM deploy

```shell
sam deploy
```

This sample is based on Serverless Application Model (SAM). To deploy it, check out the instructions for getting
started with SAM in [the examples directory](../../README.md)

## Test the application

First, hit the URL of the application. You can do this with curl or your browser:

```bash
curl https://[REST-API-ID].execute-api.[REGION].amazonaws.com/Prod/params/
```
You will get your IP address back. The contents of the logs will be more interesting, and show you the values
of the parameters injected into the handler:

```bash
sam logs --stack-name $MY_STACK_NAME --tail
```

```json
{
...
"thread": "main",
"level": "INFO",
"loggerName": "org.demo.parameters.ParametersFunction",
"message": "secretjsonobj=MyObject{id=23443, code='hk38543oj24kn796kp67bkb234gkj679l68'}\n",
...
}
```
204 changes: 204 additions & 0 deletions examples/powertools-examples-parameters/sam-graalvm/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>software.amazon.lambda.examples</groupId>
<version>2.0.0-SNAPSHOT</version>
<artifactId>powertools-examples-parameters-sam-graalvm</artifactId>
<packaging>jar</packaging>
<name>Powertools for AWS Lambda (Java) - Examples - Parameters</name>

<properties>
<log4j.version>2.24.0</log4j.version>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<aspectj.version>1.9.20.1</aspectj.version>
</properties>

<dependencies>
<dependency>
<groupId>software.amazon.lambda</groupId>
<artifactId>powertools-logging-log4j</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.lambda</groupId>
<artifactId>powertools-parameters-ssm</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>software.amazon.lambda</groupId>
<artifactId>powertools-parameters-secrets</artifactId>
<version>${project.version}</version>
</dependency>

<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>3.15.0</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-runtime-interface-client</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j2-impl</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-layout-template-json</artifactId>
<version>${log4j.version}</version>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.1.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.11.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<!-- JUnit 5 requires Surefire version 3.1.0 or higher -->
<version>3.2.5</version>
</plugin>
<plugin>
<groupId>dev.aspectj</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.14</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
<complianceLevel>${maven.compiler.target}</complianceLevel>
<aspectLibraries>
<aspectLibrary>
<groupId>software.amazon.lambda</groupId>
<artifactId>powertools-parameters</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.version}</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.6.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.logging.log4j.maven.plugins.shade.transformer.Log4j2PluginCacheFileTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-transform-maven-shade-plugin-extensions</artifactId>
<version>0.1.0</version>
</dependency>
</dependencies>
</plugin>
<!-- Don't deploy the example -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>native-image</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>0.10.1</version>
<extensions>true</extensions>
<executions>
<execution>
<id>build-native</id>
<goals>
<goal>build</goal>
</goals>
<phase>package</phase>
</execution>
</executions>
<configuration>
<imageName>hello-world</imageName>
<mainClass>com.amazonaws.services.lambda.runtime.api.client.AWSLambda</mainClass>
<buildArgs>
<!-- required for AWS Lambda Runtime Interface Client -->
<arg>--enable-url-protocols=http</arg>
<arg>--add-opens java.base/java.util=ALL-UNNAMED</arg>
</buildArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/bash
set -e

./hello-world $_HANDLER
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"name":"com.amazonaws.services.lambda.runtime.LambdaRuntime",
"methods":[{"name":"<init>","parameterTypes":[] }],
"fields":[{"name":"logger"}],
"allPublicMethods":true
},
{
"name":"com.amazonaws.services.lambda.runtime.LambdaRuntimeInternal",
"methods":[{"name":"<init>","parameterTypes":[] }],
"allPublicMethods":true
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
[
{
"name": "com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allDeclaredConstructors": true
},
{
"name": "com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent$ProxyRequestContext",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allDeclaredConstructors": true
},
{
"name": "com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent$RequestIdentity",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allDeclaredConstructors": true
},
{
"name": "com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent",
"allDeclaredFields": true,
"allDeclaredMethods": true,
"allDeclaredConstructors": true
},
{
"name": "com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent",
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"allDeclaredClasses": true,
"allPublicClasses": true
}
]
Loading
Loading