Skip to content
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

Update fortune-demo the README and yml files. #213

Merged
merged 7 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion .github/workflows/fortune-demo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ jobs:
- uses: actions/checkout@v3
- uses: graalvm/setup-graalvm@v1
with:
version: ${{ matrix.version }}
java-version: '17.0.7'
distribution: 'graalvm'
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Run 'fortune'
run: |
cd fortune-demo/fortune
cd fortune-demo/fortune-maven
./build.sh
- name: Run 'fortune-gradle'
run: |
Expand Down
74 changes: 54 additions & 20 deletions fortune-demo/README.md
Original file line number Diff line number Diff line change
@@ -1,48 +1,52 @@
# Java Fortune Demo For GraalVM Dashboard

The Fortune demo is provided to showcase the applicability of [GraalVM Dashboard](https://www.graalvm.org/docs/tools/dashboard/) - a web-based tool that visualizes the composition of a native executable. (For more information, see [Native Image](https://www.graalvm.org/reference-manual/native-image/)).
The Fortune demo is provided to showcase the applicability of [GraalVM Dashboard](https://www.graalvm.org/docs/tools/dashboard/) - a web-based tool that visualizes the composition of a native executable. (Go to the [GraalVM website](https://www.graalvm.org/reference-manual/native-image/) to learn more about Native Image).

The demo is a Java program that simulates the traditional `fortune` Unix program (for more information, see [fortune](https://en.wikipedia.org/wiki/Fortune_(Unix))). The data for the fortune phrases is provided by [YourFortune](https://github.com/your-fortune).

The Fortune demo is comprised of two sub-projects, each built with Maven: Fortune and StaticFortune.
The `pom.xml` file of each sub-project includes the [Maven plugin from Native Image Build Tools](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html), which instructs Maven to generate a native executable from a JAR file with all dependencies.
This demo is a little more complicated than HelloWorld, and requires pre-configuration before building a native executable. The Native Image Maven plugin can generate the required configuration for you by injecting the Java agent at package time.
The Fortune demo is comprised of three sub-projects:
- The _fortune-maven_ project uses the [Maven plugin for GraalVM Native Image building](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html).
- The _fortune-gradle_ project uses the [Gradle plugin for GraalVM Native Image building](https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html).
- The _staticfortune_ project demonstrates how to build a statically linked native executable using the [Maven plugin for GraalVM Native Image building](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html).

This demo is a little more complicated than _HelloWorld_, and requires pre-configuration before building a native executable. The Maven and Gradle plugins for Native Image building can generate the required configuration for you by injecting the Java agent at package time.
The plugin will also gather the diagnostic data at build time and write it to a dump file in the `target` directory.

## Preparation

1. Download and install the latest GraalVM JDK with Native Image using the [GraalVM JDK Downloader](https://github.com/graalvm/graalvm-jdk-downloader).
1. Download and install the latest GraalVM JDK using [SDKMAN!](https://sdkman.io/).
```bash
bash <(curl -sL https://get.graalvm.org/jdk)
sdk install java 17.0.9-graal
```
2. Download or clone GraalVM demos repository:
```bash
git clone https://github.com/graalvm/graalvm-demos
```

## Fortune
1. Navigate into the `fortune-demo/fortune` directory:
## Fortune Maven Demo

1. Change to the _fortune-demo/fortune-maven_ directory:
```bash
cd fortune-demo/fortune
cd fortune-demo/fortune-maven
```

2. Build the project:
```bash
mvn clean package
```
3. When the build succeeds, run the application on a JVM with the [Java agent](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#agent-support). Since you have installed GraalVM, it will run on GraalVM JDK.
3. Run your application with the [agent](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#agent-support), on the JVM:
```bash
mvn -Pnative -Dagent exec:exec@java-agent
```
The application will return a random saying.
The agent generates the configuration files in the `target/native/agent-output` subdirectory.
The agent generates the configuration files in the _target/native/agent-output_ subdirectory.

4. Build a native executable of this application with GraalVM Native Image and Maven:
```bash
mvn -Pnative -Dagent package
```
When the command completes, a native executable, `fortune`, is generated in the `/target` directory of the project and ready for use.
The diagnostic data for GraalVM Dashboard is written to a dump file `/target/fortune.bgv`.
When the command completes, a native executable, `fortune`, is generated in the _target_ directory of the project and ready for use.
The diagnostic data for GraalVM Dashboard is written to a dump file _target/fortune.bgv_.

5. Run the application by launching a native executable directly or with the Maven profile:

Expand All @@ -53,9 +57,39 @@ The plugin will also gather the diagnostic data at build time and write it to a
mvn -Pnative exec:exec@native
```

## Fortune Gradle Demo

1. Change to the _fortune-demo/fortune-gradle_ directory:
```bash
cd ../fortune-gradle
```

2. Build the project:
```bash
./gradlew run
```
3. Run your application with the [agent](https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html#agent-support), on the JVM. To enable the agent with the Native Image Gradle plugin, pass the `-Pagent` option to any Gradle tasks that extends `JavaForkOptions`:
```bash
./gradlew -Pagent run
```
The agent captures and records the dynamic features encountered during a test run into multiple *-config.json files.
4. Once the metadata is collected, copy it into the project’s _/META-INF/native-image/_ directory using the `metadataCopy` task:
```bash
./gradlew metadataCopy --task run --dir src/main/resources/META-INF/native-image
```
5. Build a native executable using configuration collected by the agent:
```bash
./gradlew nativeCompile
```
When the command completes, a native executable, `fortune`, is generated in the _build/native/nativeCompile_ directory of the project and ready for use.
6. Run the application from the native executable:
```bash
./fortune/build/native/nativeCompile/fortune
```

## StaticFortune

The StaticFortune project contains an enhanced version of the same application.
The StaticFortune project contains an enhanced version of the same application and uses the [Maven plugin for GraalVM Native Image building](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html).

1. Change to the project directory:
```bash
Expand All @@ -65,19 +99,18 @@ The StaticFortune project contains an enhanced version of the same application.
```bash
mvn clean package
```

3. Run the application on a JVM (GraalVM JDK) with the [Java agent](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#agent-support):
3. Run your application with the [agent](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html#agent-support), on the JVM:
```bash
mvn -Pnative -Dagent exec:exec@java-agent
```
The application will print a random saying.
The agent generates the configuration files in the `target/native/agent-output` subdirectory.
The agent generates the configuration files in the _target/native/agent-output_ subdirectory.
4. Build a static native executable:
```bash
mvn -Pnative -Dagent package
```
When the command completes, a native executable, `staticfortune`, is generated in the `/target` directory of the project and ready for use.
The diagnostic data for GraalVM Dashboard is written to a dump file `/target/staticfortune.bgv`.
When the command completes, a native executable, `staticfortune`, is generated in the _target_ directory of the project and ready for use.
The diagnostic data for GraalVM Dashboard is written to a dump file _target/staticfortune.bgv_.
5. Run the demo by launching a native executable directly or with the Maven profile:
```bash
./target/staticfortune
Expand All @@ -90,4 +123,5 @@ To see the benefits of executing these applications as native executables, time

### Learn More

Learn more about Native Image and static linking [here](https://www.graalvm.org/latest/reference-manual/native-image/guides/build-static-executables/).
- [Native Image and Static Linking](https://www.graalvm.org/latest/reference-manual/native-image/guides/build-static-executables/)
- [Native Build Tools](https://graalvm.github.io/native-build-tools/latest/index.html)
10 changes: 2 additions & 8 deletions fortune-demo/fortune-gradle/build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,12 @@
# Exit on error
set -e

# Compile the project and build a native executable
./gradlew nativeRun
# Run the native executable
./fortune/build/native/nativeCompile/fortune
# Run the application with the agent on JVM
./gradlew -Pagent run
# Copy metadata into /META-INF/native-image directory
./gradlew metadataCopy --task run --dir src/main/resources/META-INF/native-image
# Build a native executable using metadata
./gradlew nativeCompile
# Run the native executable
./fortune/build/native/nativeCompile/fortune
# Build a native executable using configuration (`nativeRun` compiles the app, then invokes `nativeCompile`, and then runs the native binary)
./gradlew nativeRun
# Run JUnit tests
./gradlew nativeTest
# Run tests on JVM with the agent
Expand Down
12 changes: 8 additions & 4 deletions fortune-demo/fortune-gradle/fortune/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
plugins {
// Apply the application plugin to add support for building a CLI application in Java.
id 'application'
id 'org.graalvm.buildtools.native' version '0.9.18'
id 'org.graalvm.buildtools.native' version '0.9.28'
}

repositories {
Expand All @@ -19,7 +19,9 @@ repositories {

dependencies {
// Use JUnit Jupiter for testing.
testImplementation 'org.junit.jupiter:junit-jupiter:5.8.1'
testImplementation 'org.junit.jupiter:junit-jupiter:5.9.2'
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

implementation 'com.fasterxml.jackson.core:jackson-core:2.13.2'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.13.2.2'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.13.2'
Expand All @@ -36,8 +38,10 @@ tasks.named('test') {
}

graalvmNative {
binaries.all {
resources.autodetect()
binaries {
main {
imageName.set('fortune')
}
}
toolchainDetection = false
}
2 changes: 1 addition & 1 deletion fortune-demo/fortune-gradle/settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,4 @@ pluginManagement {
}

rootProject.name = 'fortune-parent'
include('fortune')
include('fortune')
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
set -e

mvn clean compile
# Running the agent
# Run the agent
mvn -Pnative -Dagent exec:exec@java-agent
# Building the native executable
# Build the native executable
mvn -Pnative -Dagent package
# Running the application with Maven and as a native executable
# Run the application with Maven and from a native executable
mvn -Pnative exec:exec@native
./target/fortune
Loading