Skip to content

feat(v2): Add GraalVM reachability metadata for core utilities #1753

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 24 commits into from
Mar 13, 2025
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
fd40160
Initial version of PT common GraalVM reachability metadata
rr-on-gh Nov 29, 2024
ee03ae4
Initial version of PT logging GraalVM reachability metadata
rr-on-gh Nov 29, 2024
866fd82
Initial version of PT serialization GraalVM reachability metadata
rr-on-gh Nov 29, 2024
b72280f
Initial version of PT logging log4j GraalVM reachability metadata
rr-on-gh Nov 29, 2024
97650c0
Initial version of PT logging log4j GraalVM reachability metadata
rr-on-gh Nov 29, 2024
276984d
Initial version of PT logging logback GraalVM reachability metadata
rr-on-gh Nov 29, 2024
63105bf
Example of PT logging with GraalVM
rr-on-gh Dec 2, 2024
1a2cad2
Added GRM for powertools-metrics and update the example
rr-on-gh Dec 3, 2024
90fe66e
Added GRM for powertools-metrics and update the example
rr-on-gh Dec 3, 2024
617a57c
Cleanup of junit and mockito references
rr-on-gh Dec 3, 2024
a0791a4
Cleanup of junit and mockito references
rr-on-gh Dec 3, 2024
7bfedb3
Added documentation
rr-on-gh Dec 5, 2024
e867523
Added GraalVM documentation
rr-on-gh Mar 7, 2025
9b0b623
Added GraalVM documentation
rr-on-gh Mar 7, 2025
9759aad
Merge branch 'v2' into graalvm-logging-v2
phipag Mar 10, 2025
13f5cc4
Added GRM files for tracing module. Also changed the tests to use @Se…
rr-on-gh Mar 10, 2025
c45325a
Merge remote-tracking branch 'origin/graalvm-logging-v2' into graalvm…
rr-on-gh Mar 10, 2025
a969e3c
Switch commons module to use JUnit Pioneer
rr-on-gh Mar 11, 2025
ea9a1a2
Switch logging module to use JUnit Pioneer
rr-on-gh Mar 11, 2025
d96539b
Switch logging-log4j module to use JUnit Pioneer
rr-on-gh Mar 11, 2025
d186e91
Switch metrics module to use JUnit Pioneer
rr-on-gh Mar 11, 2025
e879e06
Fix testGetVersionFromProperties_InvalidFile test when running as nat…
phipag Mar 12, 2025
a1651ae
Cleaned up documentation and fixed review comments
rr-on-gh Mar 12, 2025
9b2b6e8
Cosmetic fixes/formatting. Re-order imports in changed test files, fi…
phipag Mar 13, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@ This file defines the Lambda function to be deployed as well as API Gateway for
- Set the environment to use GraalVM

```shell
export JAVA_HOME=<path to GraalVM>
````
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-core-sam-graalvm
docker build --platform linux/amd64 . -t powertools-examples-core-sam-graalvm
```

- Build the SAM project using the docker image
```shell
sam build --use-container --build-image powertools-examples-core-sam-graalvm
sam build --use-container --build-image powertools-examples-core-sam-graalvm

```
#### [Optional] Building with -SNAPSHOT versions of PowerTools
Expand Down
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<maven.deploy.plugin.version>3.1.2</maven.deploy.plugin.version>
<log4j.version>2.24.0</log4j.version>
<log4j.version>2.24.3</log4j.version>
<slf4j.version>2.0.7</slf4j.version>
<jackson.version>2.17.2</jackson.version>
<aws.sdk.version>2.28.1</aws.sdk.version>
Expand Down
18 changes: 11 additions & 7 deletions powertools-common/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,11 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
Expand Down Expand Up @@ -90,7 +95,10 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<argLine>-Dmockito.mock.maker=subclass -Dorg.graalvm.nativeimage.imagecode=agent -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image/software.amazon.lambda/powertools-common,experimental-class-define-support</argLine>
<argLine>-Dmockito.mock.maker=subclass -Dorg.graalvm.nativeimage.imagecode=agent -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image/software.amazon.lambda/powertools-common,experimental-class-define-support
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
Expand Down Expand Up @@ -123,20 +131,16 @@
</execution>
</executions>
<configuration>
<agent>
<enabled>true</enabled>
<defaultMode>Standard</defaultMode>
</agent>
<imageName>powertools-common</imageName>
<buildArgs>
<buildArg>--add-opens java.base/java.util=ALL-UNNAMED</buildArg>
<buildArg>--add-opens java.base/java.lang=ALL-UNNAMED</buildArg>
<buildArg>--no-fallback</buildArg>
<buildArg>-Dorg.graalvm.nativeimage.imagecode=agent</buildArg>
<buildArg>-H:ClassInitialization=net.bytebuddy.ClassFileVersion:rerun</buildArg>
<buildArg>-H:ClassInitialization=net.bytebuddy.utility.dispatcher.JavaDispatcher:rerun</buildArg>
<buildArg>-H:ClassInitialization=net.bytebuddy.utility.Invoker$Dispatcher:rerun</buildArg>
<buildArg>-H:ClassInitialization=net.bytebuddy.utility.GraalImageCode:rerun</buildArg>
<buildArg>-H:IncludeResources=version.properties</buildArg>
<buildArg>-H:IncludeResources=unreadable.properties</buildArg>
<buildArg>--initialize-at-build-time=org.slf4j.simple.SimpleLogger</buildArg>
<buildArg>--initialize-at-build-time=org.slf4j.LoggerFactory</buildArg>
<buildArg>--initialize-at-build-time=org.junit.Ignore</buildArg>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@

import static software.amazon.lambda.powertools.common.internal.SystemWrapper.getenv;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.io.InputStream;
import java.util.Properties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand Down Expand Up @@ -66,11 +65,12 @@ static String getProjectVersion() {
*/
static String getVersionFromProperties(String propertyFileName, String versionKey) {

URL propertiesFileURI = Thread.currentThread().getContextClassLoader().getResource(propertyFileName);
if (propertiesFileURI != null) {
try (FileInputStream fis = new FileInputStream(propertiesFileURI.getPath())) {
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(propertyFileName);

if (is != null) {
try {
Properties properties = new Properties();
properties.load(fis);
properties.load(is);
String version = properties.getProperty(versionKey);
if (version != null && !version.isEmpty()) {
return version;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,10 @@
"queryAllDeclaredConstructors":true,
"methods":[{"name":"<init>","parameterTypes":[] }, {"name":"clone","parameterTypes":[] }, {"name":"getClass","parameterTypes":[] }, {"name":"toString","parameterTypes":[] }]
},
{
"name":"java.lang.ProcessEnvironment",
"fields":[{"name":"theCaseInsensitiveEnvironment"}, {"name":"theEnvironment"}]
},
{
"name":"java.lang.ProcessHandle",
"methods":[{"name":"current","parameterTypes":[] }, {"name":"pid","parameterTypes":[] }]
Expand Down Expand Up @@ -132,6 +136,10 @@
"name":"java.security.AccessController",
"methods":[{"name":"doPrivileged","parameterTypes":["java.security.PrivilegedAction"] }, {"name":"doPrivileged","parameterTypes":["java.security.PrivilegedExceptionAction"] }]
},
{
"name":"java.util.Collections$UnmodifiableMap",
"fields":[{"name":"m"}]
},
{
"name":"java.util.concurrent.ForkJoinTask",
"fields":[{"name":"aux"}, {"name":"status"}]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.when;
import static software.amazon.lambda.powertools.common.internal.SystemWrapper.getenv;

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
Expand All @@ -30,7 +28,8 @@
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.junitpioneer.jupiter.ClearEnvironmentVariable;
import org.junitpioneer.jupiter.SetEnvironmentVariable;

class LambdaHandlerProcessorTest {

Expand Down Expand Up @@ -139,27 +138,23 @@ void placedOnStreamHandler_shouldInvalidateOnTypeOfArgs_invalidContextArg() {
}

@Test
@SetEnvironmentVariable(key = LambdaConstants.X_AMZN_TRACE_ID, value = "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\"")
void getXrayTraceId_present() {
String traceID = "Root=1-5759e988-bd862e3fe1be46a994272793;Parent=53995c3f42cd8ad8;Sampled=1\"";
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(LambdaConstants.X_AMZN_TRACE_ID)).thenReturn(traceID);

Optional xRayTraceId = LambdaHandlerProcessor.getXrayTraceId();
Optional xRayTraceId = LambdaHandlerProcessor.getXrayTraceId();

assertThat(xRayTraceId.isPresent()).isTrue();
assertThat(traceID.split(";")[0].replace(LambdaConstants.ROOT_EQUALS, "")).isEqualTo(xRayTraceId.get());
}
assertThat(xRayTraceId.isPresent()).isTrue();
assertThat(traceID.split(";")[0].replace(LambdaConstants.ROOT_EQUALS, "")).isEqualTo(xRayTraceId.get());
}

@Test
@ClearEnvironmentVariable(key = LambdaConstants.X_AMZN_TRACE_ID)
void getXrayTraceId_notPresent() {
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(LambdaConstants.X_AMZN_TRACE_ID)).thenReturn(null);

boolean isXRayTraceIdPresent = LambdaHandlerProcessor.getXrayTraceId().isPresent();
boolean isXRayTraceIdPresent = LambdaHandlerProcessor.getXrayTraceId().isPresent();

assertThat(isXRayTraceIdPresent).isFalse();
}
assertThat(isXRayTraceIdPresent).isFalse();
}

@Test
Expand Down Expand Up @@ -209,37 +204,28 @@ void isColdStart_coldStartDone() {
}

@Test
@SetEnvironmentVariable(key = LambdaConstants.AWS_SAM_LOCAL, value = "true")
void isSamLocal() {
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(LambdaConstants.AWS_SAM_LOCAL)).thenReturn("true");

boolean isSamLocal = LambdaHandlerProcessor.isSamLocal();
boolean isSamLocal = LambdaHandlerProcessor.isSamLocal();

assertThat(isSamLocal).isTrue();
}
assertThat(isSamLocal).isTrue();
}

@Test
@SetEnvironmentVariable(key = LambdaConstants.POWERTOOLS_SERVICE_NAME, value = "MyService")
void serviceName() {
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
String expectedServiceName = "MyService";
mockedSystemWrapper.when(() -> getenv(LambdaConstants.POWERTOOLS_SERVICE_NAME))
.thenReturn(expectedServiceName);
String expectedServiceName = "MyService";
String actualServiceName = LambdaHandlerProcessor.serviceName();

String actualServiceName = LambdaHandlerProcessor.serviceName();

assertThat(actualServiceName).isEqualTo(expectedServiceName);
}
assertThat(actualServiceName).isEqualTo(expectedServiceName);
}

@Test
@ClearEnvironmentVariable(key = LambdaConstants.POWERTOOLS_SERVICE_NAME)
void serviceName_Undefined() {
LambdaHandlerProcessor.resetServiceName();
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(LambdaConstants.POWERTOOLS_SERVICE_NAME)).thenReturn(null);

assertThat(LambdaHandlerProcessor.serviceName()).isEqualTo(LambdaConstants.SERVICE_UNDEFINED);
}
assertThat(LambdaHandlerProcessor.serviceName()).isEqualTo(LambdaConstants.SERVICE_UNDEFINED);
}

private ProceedingJoinPoint mockRequestHandlerPjp(Class handlerClass, Object[] handlerArgs) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,16 @@
package software.amazon.lambda.powertools.common.internal;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mockStatic;
import static software.amazon.lambda.powertools.common.internal.UserAgentConfigurator.AWS_EXECUTION_ENV;
import static software.amazon.lambda.powertools.common.internal.UserAgentConfigurator.VERSION_KEY;
import static software.amazon.lambda.powertools.common.internal.UserAgentConfigurator.VERSION_PROPERTIES_FILENAME;
import static software.amazon.lambda.powertools.common.internal.UserAgentConfigurator.getVersionFromProperties;
import static software.amazon.lambda.powertools.common.internal.SystemWrapper.getenv;


import java.io.File;
import java.util.Objects;
import java.util.regex.Pattern;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;
import org.junitpioneer.jupiter.SetEnvironmentVariable;

class UserAgentConfiguratorTest {

Expand Down Expand Up @@ -110,15 +107,13 @@ void testGetUserAgent_NullFeature() {
}

@Test
@SetEnvironmentVariable(key = AWS_EXECUTION_ENV, value = "AWS_Lambda_java8")
void testGetUserAgent_SetAWSExecutionEnv() {
try (MockedStatic<SystemWrapper> mockedSystemWrapper = mockStatic(SystemWrapper.class)) {
mockedSystemWrapper.when(() -> getenv(AWS_EXECUTION_ENV)).thenReturn("AWS_Lambda_java8");
String userAgent = UserAgentConfigurator.getUserAgent("test-feature");

assertThat(userAgent)
.isNotNull()
.isEqualTo("PT/test-feature/" + VERSION + " PTEnv/AWS_Lambda_java8");
}
String userAgent = UserAgentConfigurator.getUserAgent("test-feature");

assertThat(userAgent)
.isNotNull()
.isEqualTo("PT/test-feature/" + VERSION + " PTEnv/AWS_Lambda_java8");
}

}
16 changes: 11 additions & 5 deletions powertools-logging/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,11 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
Expand Down Expand Up @@ -116,7 +121,10 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<argLine>-Dmockito.mock.maker=subclass -Dorg.graalvm.nativeimage.imagecode=agent -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image/software.amazon.lambda/powertools-logging,experimental-class-define-support</argLine>
<argLine>-Dmockito.mock.maker=subclass -Dorg.graalvm.nativeimage.imagecode=agent -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image/software.amazon.lambda/powertools-logging,experimental-class-define-support
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
Expand Down Expand Up @@ -149,12 +157,10 @@
</execution>
</executions>
<configuration>
<agent>
<enabled>true</enabled>
<defaultMode>Standard</defaultMode>
</agent>
<imageName>powertools-logging</imageName>
<buildArgs>
<buildArg>--add-opens java.base/java.util=ALL-UNNAMED</buildArg>
<buildArg>--add-opens java.base/java.lang=ALL-UNNAMED</buildArg>
<buildArg>--no-fallback</buildArg>
<buildArg>-Dorg.graalvm.nativeimage.imagecode=agent</buildArg>
<buildArg>-H:ClassInitialization=net.bytebuddy.ClassFileVersion:rerun</buildArg>
Expand Down
16 changes: 11 additions & 5 deletions powertools-logging/powertools-logging-log4j/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit-pioneer</groupId>
<artifactId>junit-pioneer</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
Expand Down Expand Up @@ -100,7 +105,10 @@
<artifactId>maven-surefire-plugin</artifactId>
<version>3.2.3</version>
<configuration>
<argLine>-Dmockito.mock.maker=subclass -Dorg.graalvm.nativeimage.imagecode=agent -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image/software.amazon.lambda/powertools-logging-log4j,experimental-class-define-support</argLine>
<argLine>-Dmockito.mock.maker=subclass -Dorg.graalvm.nativeimage.imagecode=agent -agentlib:native-image-agent=config-output-dir=src/main/resources/META-INF/native-image/software.amazon.lambda/powertools-logging-log4j,experimental-class-define-support
--add-opens java.base/java.util=ALL-UNNAMED
--add-opens java.base/java.lang=ALL-UNNAMED
</argLine>
</configuration>
</plugin>
</plugins>
Expand Down Expand Up @@ -133,12 +141,10 @@
</execution>
</executions>
<configuration>
<agent>
<enabled>true</enabled>
<defaultMode>Standard</defaultMode>
</agent>
<imageName>powertools-logging-log4j</imageName>
<buildArgs>
<buildArg>--add-opens java.base/java.util=ALL-UNNAMED</buildArg>
<buildArg>--add-opens java.base/java.lang=ALL-UNNAMED</buildArg>
<buildArg>--no-fallback</buildArg>
<buildArg>-Dorg.graalvm.nativeimage.imagecode=agent</buildArg>
<buildArg>-H:ClassInitialization=net.bytebuddy.ClassFileVersion:rerun</buildArg>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@
"queryAllDeclaredConstructors":true,
"methods":[{"name":"<init>","parameterTypes":[] }, {"name":"clone","parameterTypes":[] }, {"name":"getClass","parameterTypes":[] }, {"name":"toString","parameterTypes":[] }]
},
{
"name":"java.lang.ProcessEnvironment",
"fields":[{"name":"theCaseInsensitiveEnvironment"}, {"name":"theEnvironment"}]
},
{
"name":"java.lang.ProcessHandle",
"methods":[{"name":"current","parameterTypes":[] }, {"name":"pid","parameterTypes":[] }]
Expand Down Expand Up @@ -198,6 +202,10 @@
{
"name":"java.sql.Time"
},
{
"name":"java.util.Collections$UnmodifiableMap",
"fields":[{"name":"m"}]
},
{
"name":"java.util.concurrent.ForkJoinTask",
"fields":[{"name":"aux"}, {"name":"status"}]
Expand Down Expand Up @@ -1120,15 +1128,6 @@
"queryAllDeclaredMethods":true,
"methods":[{"name":"getInstance","parameterTypes":[] }]
},
{
"name":"org.apache.logging.log4j.layout.template.json.resolver.PowertoolsResolverTest",
"allDeclaredFields":true,
"allDeclaredClasses":true,
"queryAllDeclaredMethods":true,
"queryAllPublicMethods":true,
"queryAllDeclaredConstructors":true,
"methods":[{"name":"<init>","parameterTypes":[] }, {"name":"shouldResolveAccountId","parameterTypes":[] }, {"name":"shouldResolveColdStart","parameterTypes":[] }, {"name":"shouldResolveFunctionStringInfo","parameterTypes":["software.amazon.lambda.powertools.logging.internal.PowertoolsLoggedFields"] }, {"name":"shouldResolveMemorySize","parameterTypes":[] }, {"name":"shouldResolveSamplingRate","parameterTypes":[] }, {"name":"unknownField_shouldThrowException","parameterTypes":[] }]
},
{
"name":"org.apache.logging.log4j.layout.template.json.resolver.SourceResolverFactory",
"queryAllDeclaredMethods":true,
Expand Down
Loading