Skip to content

Commit

Permalink
Add a section to Getting Started how to build a native executable usi…
Browse files Browse the repository at this point in the history
…ng Maven or Gradle
  • Loading branch information
olyagpl committed Jun 3, 2024
1 parent 20432ff commit e87ef3c
Show file tree
Hide file tree
Showing 2 changed files with 210 additions and 52 deletions.
36 changes: 36 additions & 0 deletions docs/reference-manual/native-image/BuildOverview.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,42 @@ The syntax of the `native-image` command is:
The options passed to `native-image` are evaluated from left to right.
For an overview of options that can be passed to `native-image`, see [here](BuildOptions.md).

## Getting Notified When the Build Process Is Done

Depending on the size of your application and the available resources of your build machine, it can take a few minutes to compile your Java application into a native executable.
If you are building your application in the background, consider using a command that notifies you when the build process is completed.
Below, example commands are listed per operating system:

#### Linux
```bash
# Ring the terminal bell
native-image -jar App.jar ... ; printf '\a'

# Use libnotify to create a desktop notification
native-image -jar App.jar ... ; notify-send "GraalVM Native Image build completed with exit code $?"

# Use Zenity to open an info dialog box with text
native-image -jar App.jar ... ; zenity --info --text="GraalVM Native Image build completed with exit code $?"
```

#### macOS
```bash
# Ring the terminal bell
native-image -jar App.jar ... ; printf '\a'

# Use Speech Synthesis
native-image -jar App.jar ... ; say "GraalVM Native Image build completed"
```

#### Windows
```bash
# Ring the terminal bell (press Ctrl+G to enter ^G)
native-image.exe -jar App.jar & echo ^G

# Open an info dialog box with text
native-image.exe -jar App.jar & msg "%username%" GraalVM Native Image build completed
```

### Further Reading

If you are new to GraalVM Native Image or have little experience using it, see the [Native Image Basics](NativeImageBasics.md) to better understand some key aspects before going further.
Expand Down
226 changes: 174 additions & 52 deletions docs/reference-manual/native-image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ To get used to Native Image terminology and get better understanding of the tech

### Table of Contents

* [Build a Native Executable](#build-a-native-executable)
* [Build a Native Executable Using Maven or Gradle](#build-a-native-executable-using-maven-or-gradle)
* [Build a Native Executable Using the `native-image` Tool](#build-a-native-executable-using-the-native-image-tool)
* [Build Configuration](#build-configuration)
* [Configuring Native Image with Third-Party Libraries](#configuring-native-image-with-third-party-libraries)
* [Further Reading](#further-reading)

Expand Down Expand Up @@ -74,11 +76,167 @@ Native Image runs in both a PowerShell or Command Prompt and will automatically

For more information, see [Using GraalVM and Native Image on Windows](https://medium.com/graalvm/using-graalvm-and-native-image-on-windows-10-9954dc071311).

## Build a Native Executable
## Build a Native Executable Using Maven or Gradle

The `native-image` tool takes Java bytecode as its input. You can build a native executable from a class file, from a JAR file, or from a module (with Java 9 and higher).
We provide Maven and Gradle plugins for Native Image to automate building, testing, and configuring native executables.

### Maven

The [Maven plugin for Native Image](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html) adds support for compiling a Java application into a native executable using [Apache Maven](https://maven.apache.org/).

1. Create a new Maven Java project named “helloworld” in your favorite IDE or from your terminal with the following structure:
```
├── pom.xml
└── src
├── main
│   └── java
│   └── com
│   └── example
│   └── App.java
```
For example, you can run this command to create a new Maven project using the quickstart archetype:
```bash
mvn archetype:generate -DgroupId=com.example -DartifactId=helloworld -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false
```

2. Add the regular Maven plugins for compiling and assembling the project into an executable JAR file to your _pom.xml_ file:
```xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.12.1</version>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.App</mainClass>
<addClasspath>true</addClasspath>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
```

3. Enable the Maven plugin for Native Image by adding the following profile to _pom.xml_:
```xml
<profiles>
<profile>
<id>native</id>
<build>
<plugins>
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<version>${native.maven.plugin.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>build-native</id>
<goals>
<goal>compile-no-fork</goal>
</goals>
<phase>package</phase>
</execution>
<execution>
<id>test-native</id>
<goals>
<goal>test</goal>
</goals>
<phase>test</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
```
Set the `version` property to the latest plugin version (for example, by specifying the version via `<native.maven.plugin.version>` in the `<properties>` element).

4. Compile the project and build a native executable at one step:
```bash
mvn -Pnative package
```
The native executable, named `helloworld`, is created in the _target/_ directory of the project.

5. Run the executable:
```bash
./target/helloworld
```
That is it, you successfully created the native executable for your Java application using Maven.

The Maven plugin for Native Image building offers many other features that may be required for an application with more complexity, such as resources autodetection, generating the required configuration, running JUnit Platform tests on a native executable, and so on, described in the [plugin reference documentation](https://graalvm.github.io/native-build-tools/latest/maven-plugin.html).

### Gradle

The [Gradle plugin for Native Image](https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html) adds support for compiling a Java application into a native executable using the [Gradle build tool](https://gradle.org/).

1. Create a new Gradle Java project named “helloworld” in your favorite IDE or from your terminal with the following structure:
```
├── app
│   ├── build.gradle
│   └── src
│   ├── main
│   │   ├── java
│   │   │   └── org
│   │   │   └── example
│   │   │   └── App.java
│   │   └── resources
```

For example, initialize a new Gradle project with the `java` plugin:
- Create a new directory and enter it:
```bash
mkdir helloworld && cd helloworld
```
- Generate a project:
```bash
gradle init --project-name helloworld --type java-application --test-framework junit-jupiter --dsl groovy
```
Follow the prompts.
This command sets up a new Java application with the necessary directory structure and build files.

2. Enable the Gradle plugin for Native Image by adding the following to `plugins` section of your project’s _build.gradle_ file:
```
plugins {
// ...
id 'org.graalvm.buildtools.native' version 'x.x.x'
}
```
Specify the latest plugin version for the `'x.x.x'` version value.

3. Build a native executable by running `./gradlew nativeCompile`:
```bash
./gradlew nativeCompile
```
The native executable, named `app`, is created in the _app/build/native/nativeCompile/_ directory of the project.

4. Run the native executable:
```bash
./app/build/native/nativeCompile/app
```
That is it, you successfully created the native executable for your Java application using Gradle.

The Gradle plugin for Native Image building has many other features that may be required for an application with more complexity, such as resources autodetection, generating the required configuration, running JUnit Platform tests on a native executable, and so on, described in the [plugin reference documentation](https://graalvm.github.io/native-build-tools/latest/gradle-plugin.html).

## Build a Native Executable Using the `native-image` Tool

The `native-image` tool takes Java bytecode as its input.
You can build a native executable from a class file, from a JAR file, or from a module (with Java 9 and higher).

### From a Class

To build a native executable from a Java class file in the current working directory, use the following command:
```shell
native-image [options] class [imagename] [options]
Expand Down Expand Up @@ -137,59 +295,25 @@ native-image [options] --module <module>[/<mainclass>] [options]

For more information about how to produce a native executable from a modular Java application, see [Building a HelloWorld Java Module into a Native Executable](guides/build-java-module-app-aot.md).

### Getting Notified When the Build Process Is Done

Depending on the size of your application and the available resources of your build machine, it can take a few minutes to AOT-compile your Java application to a native executable.
If you are building your project in the background, consider using a command that notifies you when the build process is completed.
Below, example commands are listed per operating system:

#### Linux
```bash
# Ring the terminal bell
native-image -jar App.jar ... ; printf '\a'

# Use libnotify to create a desktop notification
native-image -jar App.jar ... ; notify-send "GraalVM Native Image build completed with exit code $?"

# Use Zenity to open an info dialog box with text
native-image -jar App.jar ... ; zenity --info --text="GraalVM Native Image build completed with exit code $?"
```

#### macOS
```bash
# Ring the terminal bell
native-image -jar App.jar ... ; printf '\a'

# Use Speech Synthesis
native-image -jar App.jar ... ; say "GraalVM Native Image build completed"
```

#### Windows
```bash
# Ring the terminal bell (press Ctrl+G to enter ^G)
native-image.exe -jar App.jar & echo ^G

# Open an info dialog box with text
native-image.exe -jar App.jar & msg "%username%" GraalVM Native Image build completed
```

## Build Configuration

There many options you can pass to the `native-image` builder to configure the build process. Run `native-image --help` to see the full list.
There many options you can pass to the `native-image` tool to configure the build process.
Run `native-image --help` to see the full list.
The options passed to `native-image` are evaluated left-to-right.

For different build tweaks and to learn more about build time configuration, see [Native Image Build Configuration](BuildConfiguration.md).

Native Image will output the progress and various statistics during the build. To learn more about the output and the different build phases, see [Build Output](BuildOutput.md).
Native Image will output the progress and various statistics during the build.
To learn more about the output and the different build phases, see [Build Output](BuildOutput.md).

## Native Image and Third-Party Libraries

For more complex applications that use external libraries, you must provide the `native-image` builder with metadata.
For more complex applications that use external libraries, you must provide the `native-image` tool with metadata.

Building a standalone binary with the `native-image` tool takes place under a "closed world assumption".
The `native-image` tool performs an analysis to see which classes, methods, and fields within your application are reachable and must be included in the native image.
Building a standalone binary with `native-image` takes place under a "closed world assumption".
The `native-image` tool performs an analysis to see which classes, methods, and fields within your application are reachable and must be included in the native executable.
The analysis is static: it does not run your application.
This means that all the bytecode in your application that can be called at run time must be known (observed and analyzed) at build time.
This means that all the bytecode in your application that can be called at runtime must be known (observed and analyzed) at build time.

The analysis can determine some cases of dynamic class loading, but it cannot always exhaustively predict all usages of the Java Native Interface (JNI), Java Reflection, Dynamic Proxy objects, or class path resources.
To deal with these dynamic features of Java, you inform the analysis with details of the classes that use Reflection, Proxy, and so on, or what classes to be dynamically loaded.
Expand All @@ -198,26 +322,24 @@ To achieve this, you either provide the `native-image` tool with JSON-formatted
To learn more about metadata, ways to provide it, and supported metadata types, see [Reachability Metadata](ReachabilityMetadata.md).
To automatically collect metadata for your application, see [Automatic Collection of Metadata](AutomaticMetadataCollection.md).

There are also Maven and Gradle plugins for Native Image to automate building, testing and configuring native executables. Learn more [here](https://graalvm.github.io/native-build-tools/latest/index.html).

Some applications may need additional configuration to be compiled with GraalVM Native Image.
Some applications may need additional configuration to be compiled with Native Image.
For more details, see [Native Image Compatibility Guide](Compatibility.md).

Native Image can also interop with native languages through a custom API.
Using this API, you can specify custom native entry points into your Java application and build it into a nativw shared library.
Using this API, you can specify custom native entry points into your Java application and build it into a native shared library.
To learn more, see [Interoperability with Native Code](InteropWithNativeCode.md).

### Further Reading

This getting started guide is intended for new users or those with little experience of using GraalVM Native Image.
This getting started guide is intended for new users or those with little experience of using Native Image.
We strongly recommend these users to check the [Basics of Native Image](NativeImageBasics.md) page to better understand some key aspects before going deeper.

Check [user guides](guides/guides.md) to become more experienced with GraalVM Native Image, find demo examples, and learn about potential usage scenarios.
Check [user guides](guides/guides.md) to become more experienced with Native Image, find demo examples, and learn about potential usage scenarios.

For a gradual learning process, check the Native Image [Build Overview](BuildOverview.md) and [Build Configuration](BuildConfiguration.md) documentation.

Consider running interactive workshops to get some practical experience: go to [Luna Labs](https://luna.oracle.com/) and search for "Native Image".

If you have stumbled across a potential bug, please [submit an issue in GitHub](https://github.com/oracle/graal/issues/new/choose).

If you would like to contribute to Native Image, follow our standard [contributing workflow](contribute/Contributing.md).
If you would like to contribute to Native Image, follow our standard [contributing workflow](contribute/Contributing.md).

0 comments on commit e87ef3c

Please sign in to comment.