Skip to content

Commit f4c3665

Browse files
committed
Add a GitHub workflow for preserve-package demo
1 parent 872ef4d commit f4c3665

File tree

7 files changed

+77
-36
lines changed

7 files changed

+77
-36
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
name: native-image/preserve-package
2+
on:
3+
push:
4+
paths:
5+
- 'native-image/preserve-package/**'
6+
- '.github/workflows/native-image-preserve-package.yml'
7+
pull_request:
8+
paths:
9+
- 'native-image/preserve-package/**'
10+
- '.github/workflows/native-image-preserve-package.yml'
11+
schedule:
12+
- cron: "0 0 1 * *" # run every month
13+
workflow_dispatch:
14+
permissions:
15+
contents: read
16+
jobs:
17+
run:
18+
name: Run 'native-image/preserve-package'
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 15
21+
steps:
22+
- uses: actions/checkout@v4
23+
- uses: graalvm/setup-graalvm@v1
24+
with:
25+
java-version: '25-ea'
26+
distribution: 'graalvm'
27+
github-token: ${{ secrets.GITHUB_TOKEN }}
28+
native-image-job-reports: 'true'
29+
- name: Run 'native-image/preserve-package'
30+
run: |
31+
cd native-image/preserve-package
32+
./run.sh

native-image/preserve-package/README.md

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
# Using Native Image `Preserve` Option
22

3-
[Reflection](https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/lang/reflect/package-summary.html) is a feature of the Java programming language that enables a running Java program to examine and modify attributes of its classes, interfaces, fields, and methods. GraalVM Native Image automatically supports some uses of reflection. Native Image uses static analysis to identify what classes, methods, and fields are needed by an application, but it may not detect some elements of your application that are accessed using the [Java Reflection API](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/package-summary.html). You must declare any undetected reflection usage to the `native-image` tool, either as metadata (precomputed in code or as JSON configuration files) or using the `-H:Preserve` option (experimental in GraalVM for JDK 25).
3+
Reflection is a feature of the Java programming language that enables a running Java program to examine and modify attributes of its classes, interfaces, fields, and methods.
4+
GraalVM Native Image automatically supports some uses of reflection.
5+
Native Image uses static analysis to identify what classes, methods, and fields are needed by an application, but it may not detect some elements of your application that are accessed using the [Java Reflection API](https://docs.oracle.com/en/java/javase/24/docs/api/java.base/java/lang/reflect/package-summary.html).
6+
You must declare any undetected reflection usage to the `native-image` tool, either as metadata ([precomputed in code or as JSON configuration files](https://www.graalvm.org/latest/reference-manual/native-image/metadata/)) or using the `-H:Preserve` option (experimental in GraalVM for JDK 25).
47

58
This guide demonstrates how to declare reflection configuration using the `-H:Preserve` option.
69

@@ -12,18 +15,16 @@ This guide demonstrates how to declare reflection configuration using the `-H:Pr
1215
sdk install java 25.ea.29-graal
1316
```
1417

15-
2. Download or clone this repository and navigate into the `native-image/preserve-package` directory:
18+
2. Download or clone this repository, and navigate into the `native-image/preserve-package` directory:
1619

1720
```shell
1821
git clone https://github.com/graalvm/graalvm-demos
1922
cd graalvm-demos/native-image/preserve-package
2023
```
2124

22-
## Example using Reflection on the JVM
25+
## Example Using Reflection on the JVM
2326

24-
The `ReflectionExample` class uses command line argument values to
25-
reflectively create an instance of a class and invoke a method with a
26-
provided argument. The core code is:
27+
The `ReflectionExample` class uses command line argument values to reflectively create an instance of a class and invoke a method with a provided argument. The core code is:
2728

2829
```java
2930
Class<?> clazz = Class.forName(className);
@@ -36,11 +37,10 @@ This approach works on the JVM as long as the required classes and methods are a
3637
1. Compile the application and create a JAR file using Maven:
3738

3839
```shell
39-
./mvnw package
40+
./mvnw package
4041
```
4142

42-
2. Run `ReflectionExample` (the JAR entry point) to invoke the
43-
`StringReverser` action:
43+
2. Run `ReflectionExample` (the JAR entry point) to invoke the `StringReverser` action:
4444

4545
```shell
4646
$JAVA_HOME/bin/java -jar target/preserve-package-1.0-SNAPSHOT.jar \
@@ -68,16 +68,13 @@ This approach works on the JVM as long as the required classes and methods are a
6868

6969
## GraalVM Native Image
7070

71-
You can compile the project with Native Image, specifying `ReflectionExample` as the main
72-
entry point.
73-
The [_pom.xml_](pom.xml) file uses the [GraalVM Native Build
74-
Tools](https://graalvm.github.io/native-build-tools/latest/index.html) plugin to compile the project with the `native-image` tool when you select the `native-default`
75-
profile.
71+
You can compile the project with Native Image, specifying `ReflectionExample` as the main entry point.
72+
The [_pom.xml_](pom.xml) file uses the [Native Build Tools Maven plugin](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html) to compile the project with the `native-image` tool.
7673

7774
1. Build a native executable using the `native-default` profile (see the [_pom.xml_](pom.xml) file):
7875

7976
```shell
80-
./mvnw package -Pnative-default
77+
./mvnw package -Pnative-default
8178
```
8279

8380
2. Run the resulting `example-default` native executable:
@@ -102,18 +99,20 @@ profile.
10299

103100
This error occurs because the `native-image` tool's static analysis did not determine that your application uses the `StringReverser` class, and did not include it in the native executable.
104101
105-
## Native Image using `-H:Preserve`
102+
## Native Image Using `-H:Preserve`
106103
107104
GraalVM for JDK 25 introduces the `-H:Preserve` option.
108105
109-
This option lets you instruct the `native-image` tool to keep entire packages, modules, or all classes on the classpath
106+
This option lets you instruct the `native-image` tool to keep entire packages, modules, or all classes on the classpath.
110107
111-
<!-- (which can result in very large applications). -->
108+
<!-- This can result in larger application size. -->
112109
113-
In this example, both classes used via reflection are in the `org.graalvm.example.action` package. You can use `-H:Preserve=package` to keep all of the classes in that package in the native executable, even if static analysis cannot discover them.
110+
In this example, both classes used via reflection are in the `org.graalvm.example.action` package.
111+
You can use `-H:Preserve=package` to keep all of the classes in that package in the native executable, even if static analysis cannot discover them.
114112
115-
Native Image command line arguments can be specified as `<buildArgs>` in the
116-
`native-maven-plugin` configuration. As the `-H:Preserve` option is experimental, you must also enable its use with `-H:+UnlockExperimentalVMOptions`. For the complete plugin configuration, see the [_pom.xml_](pom.xml) file:
113+
Native Image command line arguments can be specified as `<buildArgs>` in the `native-maven-plugin` configuration.
114+
Since the `-H:Preserve` option is experimental, you must also enable its use with `-H:+UnlockExperimentalVMOptions`.
115+
For the complete plugin configuration, see the [_pom.xml_](pom.xml) file:
117116
118117
```xml
119118
<configuration>
@@ -125,16 +124,13 @@ Native Image command line arguments can be specified as `<buildArgs>` in the
125124
</configuration>
126125
```
127126
128-
1. Build a native executable using the `native-preserve` profile, which adds
129-
`-H:Preserve=package=org.graalvm.example.action` when running the `native-image`
130-
tool (see the [_pom.xml_](pom.xml) file):
127+
1. Build a native executable using the `native-preserve` profile, which adds `-H:Preserve=package=org.graalvm.example.action` when running the `native-image` tool:
131128
132129
```shell
133-
./mvnw package -Pnative-preserve
130+
./mvnw package -Pnative-preserve
134131
```
135132
136-
2. Run the new `example-preserve` executable to confirm the previously missing
137-
`StringReverser` class and its methods are now included:
133+
2. Run the new `example-preserve` executable to confirm the previously missing `StringReverser` class and its methods are now included:
138134
139135
```shell
140136
./target/example-preserve \
@@ -165,5 +161,5 @@ As demonstrated, `-H:Preserve` provides an easy way to ensure that Native Image
165161
### Related Documentation
166162
167163
* [Reachability Metadata: Reflection](https://www.graalvm.org/latest/reference-manual/native-image/metadata/)
168-
* [Assisted Configuration with Tracing Agent](https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/#tracing-agent)
169-
* [java.lang.reflect Javadoc](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/package-summary.html)
164+
* [Assisted Configuration with Tracing Agent](https://www.graalvm.org/latest/reference-manual/native-image/metadata/AutomaticMetadataCollection/#tracing-agent)
165+
* [Java Reflection API](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/reflect/package-summary.html)

native-image/preserve-package/pom.xml

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
<version>1.0-SNAPSHOT</version>
99

1010
<name>preserve</name>
11-
11+
1212
<properties>
1313
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
1414
<maven.compiler.release>21</maven.compiler.release>
@@ -36,7 +36,7 @@
3636
</executions>
3737
<configuration>
3838
<mainClass>org.graalvm.example.ReflectionExample</mainClass>
39-
<imageName>example-default</imageName>
39+
<imageName>example-default</imageName>
4040
</configuration>
4141
</plugin>
4242
</plugins>
@@ -62,7 +62,7 @@
6262
</executions>
6363
<configuration>
6464
<mainClass>org.graalvm.example.ReflectionExample</mainClass>
65-
<imageName>example-preserve</imageName>
65+
<imageName>example-preserve</imageName>
6666
<buildArgs>
6767
<buildArg>-H:+UnlockExperimentalVMOptions</buildArg>
6868
<buildArg>-H:Preserve=package=org.graalvm.example.action</buildArg>
@@ -81,7 +81,6 @@
8181
<artifactId>maven-clean-plugin</artifactId>
8282
<version>3.4.0</version>
8383
</plugin>
84-
<!-- default lifecycle, jar packaging: see https://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging -->
8584
<plugin>
8685
<artifactId>maven-resources-plugin</artifactId>
8786
<version>3.3.1</version>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
#!/usr/bin/env bash
2+
set +e
3+
4+
./mvnw package
5+
$JAVA_HOME/bin/java -jar target/preserve-package-1.0-SNAPSHOT.jar \
6+
org.graalvm.example.action.StringReverser reverse "hello"
7+
8+
./mvnw package -Pnative-default
9+
./target/example-default \
10+
org.graalvm.example.action.StringReverser reverse "hello"
11+
12+
./mvnw package -Pnative-preserve
13+
./target/example-preserve \
14+
org.graalvm.example.action.StringReverser reverse "hello"

native-image/preserve-package/src/main/java/org/graalvm/example/ReflectionExample.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0

native-image/preserve-package/src/main/java/org/graalvm/example/action/StringCapitalizer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0

native-image/preserve-package/src/main/java/org/graalvm/example/action/StringReverser.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* The Universal Permissive License (UPL), Version 1.0

0 commit comments

Comments
 (0)