Skip to content

Commit

Permalink
[GR-43129] [GR-43524] Documentation: Native Image User Guides updates.
Browse files Browse the repository at this point in the history
PullRequest: graal/13525
  • Loading branch information
olyagpl committed Jan 18, 2023
2 parents 2617bc9 + 92ed601 commit 7b49365
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 87 deletions.
2 changes: 1 addition & 1 deletion docs/introduction.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ The following table lists production-ready and experimental features in GraalVM
| Python | experimental | not available | experimental | not available | not available |
| Ruby | experimental | experimental | experimental | experimental | not available |
| R | experimental | not available | experimental | not available | not available |
| WebAssembly | experimental | experimental | experimental | experimental | experimental |
| WebAssembly | experimental | experimental | experimental | not available | experimental |

## What to Read Next

Expand Down
62 changes: 2 additions & 60 deletions docs/reference-manual/native-image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,67 +144,9 @@ To build a native executable from a JAR file in the current working directory, u
native-image [options] -jar jarfile [imagename]
```

1. Prepare the application.
The default behavior of `native-image` is aligned with the `java` command which means you can pass the `-jar`, `-cp`, `-m` options to build with Native Image as you would normally do with `java`. For example, `java -jar App.jar someArgument` becomes `native-image -jar App.jar` and `./App someArgument`.

- Create a new Java project named "App", for example in your favorite IDE or from your terminal, with the following structure:

```shell
| src
| --com/
| -- example
| -- App.java
```

- Add the following Java code into the _src/com/example/App.java_ file:

```java
package com.example;
public class App {
public static void main(String[] args) {
String str = "Native Image is awesome";
String reversed = reverseString(str);
System.out.println("The reversed string is: " + reversed);
}
public static String reverseString(String str) {
if (str.isEmpty())
return str;
return reverseString(str.substring(1)) + str.charAt(0);
}
}
```
This is a small Java application that reverses a String using recursion.
2. Compile the application:
```shell
javac -d build src/com/example/App.java
```
This produces the file _App.class_ in the _build/com/example_ directory.
3. Create a runnable JAR file:
```shell
jar --create --file App.jar --main-class com.example.App -C build .
```
It will generate a runnable JAR file, named `App.jar`, in the root directory:
To view its contents, type `jar tf App.jar`.
4. Create a native executable:
```
native-image -jar App.jar
```
It will produce a native executable in the project root directory.
5. Run the native executable:
```shell
./App
```
The `native-image` tool can provide the class path for all classes using the familiar option from the java launcher: `-cp`, followed by a list of directories or JAR files, separated by `:` on Linux and macOS platforms, or `;` on Windows. The name of the class containing the `main` method is the last argument, or you can use the `-jar` option and provide a JAR file that specifies the `main` method in its manifest.
[Follow this guide](guides/build-native-executable-from-jar.md) to build a native executable from a JAR file.

### From a Module

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
---
layout: ni-docs
toc_group: how-to-guides
link_title: Build a Native Executable from a JAR File
permalink: /reference-manual/native-image/guides/build-native-executable-from-jar/
---

# Build a Native Executable from a JAR File

You can build a native executable from a class file, from a JAR file, or from a module. This guide demonstrates how to build a native executable from a JAR file.

To build a native executable from a JAR file in the current working directory, use the following command:
```shell
native-image [options] -jar jarfile [executable name]
```

1. Prepare the application.

- Create a new Java project named "App", for example in your favorite IDE or from your terminal, with the following structure:

```shell
| src
| --com/
| -- example
| -- App.java
```

- Add the following Java code to the _src/com/example/App.java_ file:

```java
package com.example;
public class App {
public static void main(String[] args) {
String str = "Native Image is awesome";
String reversed = reverseString(str);
System.out.println("The reversed string is: " + reversed);
}
public static String reverseString(String str) {
if (str.isEmpty())
return str;
return reverseString(str.substring(1)) + str.charAt(0);
}
}
```
This is a small Java application that reverses a String using recursion.
2. Compile the application:
```shell
javac -d build src/com/example/App.java
```
This produces the file _App.class_ in the _build/com/example_ directory.
3. Create a runnable JAR file:
```shell
jar --create --file App.jar --main-class com.example.App -C build .
```
It will generate a runnable JAR file, named _App.jar_, in the project root directory:
To view its contents, run the command `jar tf App.jar`.
4. Create a native executable:
```
native-image -jar App.jar
```
It will produce a native executable in the project root directory.
5. Run the native executable:
```shell
./App
```
The default behavior of `native-image` is aligned with the `java` command which means you can pass the `-jar`, `-cp`, `-m` options to build with Native Image as you would normally do with `java`. For example, `java -jar App.jar someArgument` becomes `native-image -jar App.jar` and `./App someArgument`.
### Related Documentation
* [GraalVM Native Image Quick Start](https://luna.oracle.com/lab/47dafec8-4095-4fba-8313-dad43a64dee4)
* [Build Java Modules into a Native Executable](build-java-module-app-aot.md)
28 changes: 17 additions & 11 deletions docs/reference-manual/native-image/guides/build-with-reflection.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
---
layout: ni-docs
toc_group: how-to-guides
link_title: Build with Reflection
permalink: /reference-manual/native-image/guides/build-with-reflection/
link_title: Configure Native Image with the Tracing Agent
permalink: /reference-manual/native-image/guides/configure-with-tracing-agent/
redirect_from:
- /reference-manual/native-image/guides/build-with-reflection/
---

# Build a Native Executable with Reflection
# Configure Native Image with the Tracing Agent

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.
To build a native executable for a Java application that uses Java reflection, dynamic proxy objects, JNI, or class path resources, you should either provide the `native-image` tool with JSON-formatted configuration files or pre-compute metadata in the code.

The `native-image` utility provides partial support for reflection. It uses static analysis to detect the elements of your application that are accessed using the Java Reflection API. However, because the analysis is static, it cannot always completely predict all usages of the API when the program runs. In these cases, you must provide a configuration file to the native-image utility to specify the program elements that use the API.
You can create configuration file(s) by hand, but a more convenient approach is to generate the configuration using the Tracing agent (from now on, the agent).
This guide demonstrates how to configure `native-image` with the agent. The agent generates the configuration for you automatically when you run an application on a JVM.

To learn how to build a native executable with the metadata pre-computed in the code, [follow this guide](use-reachability-metadata-repository-gradle.md).

The example application in this guide uses Java reflection. The `native-image` tool only partially detects application elements that are accessed using the Java Reflection API. So, you need to provide it with details about reflectively accessed classes, methods, and fields.
## Example with No Configuration

The following application demonstrates the use of Java reflection.

1. Save the following source code in a file named _ReflectionExample.java_:
Expand Down Expand Up @@ -78,16 +85,15 @@ The following application demonstrates the use of Java reflection.
is used by the application and therefore did not include it in the native executable.

## Example with Configuration
To build a native executable containing references to the classes and methods that are accessed via reflection, provide the `native-image` utility with a configuration file that specifies the classes and corresponding methods. (For more information about configuration files, see [Reflection Use in Native Images](../Reflection.md).) You can create this file by hand, but a more convenient approach is to generate the configuration using the tracing agent. The agent generates the configuration for you automatically when you run your application (for more information, see [Assisted Configuration with Tracing Agent](../AutomaticMetadataCollection.md#tracing-agent).

The following steps demonstrate how to use the javaagent tool, and its output, to create a native executable that relies on reflection.
The following steps demonstrate how to use the agent, and its output, to create a native executable that relies on reflection and requires configuration.

1. Create a directory `META-INF/native-image` in the working directory:
1. Create a directory named _META-INF/native-image_ in the working directory:
```shell
mkdir -p META-INF/native-image
```

2. Run the application with the tracing agent enabled, as follows:
2. Run the application with the agent enabled, as follows:
```shell
$JAVA_HOME/bin/java -agentlib:native-image-agent=config-output-dir=META-INF/native-image ReflectionExample StringReverser reverse "hello"
```
Expand Down Expand Up @@ -140,7 +146,7 @@ The following steps demonstrate how to use the javaagent tool, and its output, t
]
```

6. Rebuild a native executable and run the resulting file.
6. Rebuild the native executable and run it.
```shell
$JAVA_HOME/bin/native-image ReflectionExample
./reflectionexample StringCapitalizer capitalize "hello"
Expand All @@ -150,6 +156,6 @@ The following steps demonstrate how to use the javaagent tool, and its output, t

### Related Documentation

* [Assisted Configuration with Tracing Agent](../AutomaticMetadataCollection.md#tracing-agent)
* [Reachability Metadata: Reflection](../ReachabilityMetadata.md#reflection)
* [Assisted Configuration with Tracing Agent](../AutomaticMetadataCollection.md#tracing-agent)
* [java.lang.reflect Javadoc](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/reflect/package-summary.html)
Original file line number Diff line number Diff line change
Expand Up @@ -28,14 +28,61 @@ This will enable source-level debugging, and the debugger (GDB) then correlates
Follow the steps to test debugging a native executable with GDB. The below workflow is know to work on Linux OS with GDB 10.1.

1. Save the following code to the file named _GDBDemo.java_.
```java
public class GDBDemo {
static long fieldUsed = 1000;

public static void main( String[] args ) {
if (args.length > 0) {
int n = -1;
try {
n = Integer.parseInt(args[0]);
} catch (NumberFormatException ex) {
System.out.println(args[0] + " is not a number!");
}
if (n < 0) {
System.out.println(args[0] + " is negative.");
}
double f = factorial(n);
System.out.println(n + "! = " + f);
}

if (false)
neverCalledMethod();

StringBuilder text = new StringBuilder();
text.append("Hello World from GraalVM Native Image and GDB in Java.\n");
System.out.println(text.toString());
}

static void neverCalledMethod() {
System.out.println("This method is unreachable and will not be included in the native executable.");
}

static double factorial(int n) {
if (n == 0) {
return 1;
}
if (n >= fieldUsed) {
return Double.POSITIVE_INFINITY;
}
double f = 1;
while (n > 1) {
f *= n--;
}
return f;
}
}

```

2. Compile it and generate a native executable with debug information:

```shell
$JAVA_HOME/bin/javac JFRDemo.java
$JAVA_HOME/bin/javac GDBDemo.java
```
```shell
native-image -g -O0 JFRDemo
native-image -g -O0 GDBDemo
```
The `-g` option instructs `native-image` to generate debug information. The resulting native executable will contain debug records in a format GDB understands.

Expand All @@ -44,7 +91,7 @@ Follow the steps to test debugging a native executable with GDB. The below workf
3. Launch the debugger and run your native executable:

```shell
gdb ./jfrdemo
gdb ./gdbdemo
```
The `gdb` prompt will open.

Expand Down
14 changes: 8 additions & 6 deletions docs/reference-manual/native-image/guides/guides.md
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
---
layout: ni-docs
layout: ni-docs-landing
toc_group: how-to-guides
link_title: How-to Guides
permalink: /reference-manual/native-image/guides/
link_title: User Guides
permalink: /native-image/guides/
redirect_from: /reference-manual/native-image/guides/
---

# Native Image How-to Guides
# Native Image User Guides

These guides are to help developers get started with GraalVM Native Image, acquaint them with the available features, and describe potential usage scenarios.
These guides help developers get started with GraalVM Native Image, acquaint them with available features, and describe potential usage scenarios.
Here you will learn how to:

- [Access Environment Variables](access-environment-variables.md)
- [Add Logging to a Native Executable](add-logging-to-native-executable.md)
- [Build a Native Executable from a JAR File](build-native-executable-from-jar.md)
- [Build and Run Native Executables with JFR](build-and-run-native-executable-with-jfr.md)
- [Build Java Modules into a Native Executable](build-java-module-app-aot.md)
- [Build a Native Shared Library](build-native-shared-library.md)
- [Build a Polyglot Native Executable (Java and JavaScript)](build-polyglot-native-executable.md)
- [Build a Static or Mostly-Static Native Executable](build-static-and-mostly-static-executable.md)
- [Build a Native Executable with Reflection](build-with-reflection.md)
- [Configure Native Image with the Tracing Agent](build-with-reflection.md)
- [Containerise a Native Executable and Run in a Docker Container](containerise-native-executable-with-docker.md)
- [Create a Heap Dump from a Native Executable](create-heap-dump-from-native-executable.md)
- [Debug Native Executables with GDB](debug-native-executables-with-gdb.md)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -186,4 +186,4 @@ With PGO you "train" your application for specific workloads and significantly i

### Related Documentation

- [Improving performance of GraalVM native images with profile-guided optimizations](https://medium.com/graalvm/improving-performance-of-graalvm-native-images-with-profile-guided-optimizations-9c431a834edb)
- [Optimize Cloud Native Java Apps with GraalVM Enterprise PGO](https://luna.oracle.com/lab/3f0b7c86-6105-4b7a-9a3b-eb73b251a1aa)
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
---
layout: ni-docs
toc_group: how-to-guides
link_title: Use Shared Reachability Metadata with Native Image Gradle Plugin
link_title: Configure Native Image Using Shared Reachability Metadata
permalink: /reference-manual/native-image/guides/use-reachability-metadata-repository-gradle/
---

# Use Shared Reachability Metadata with Native Image Gradle Plugin
# Configure Native Image Using Shared Reachability Metadata

With the Gradle plugin for GraalVM Native Image you can easily build a native executable from a Java application. The plugin is provided as part of the [Native Build Tools project](https://graalvm.github.io/native-build-tools/latest/index.html) and uses the [Gradle build tool](https://gradle.org/).
If the application does not load dynamically any classes at run time, then your workflow is just one command: `./gradlew nativeRun`.
If the application does not dynamically load any classes at run time, then your workflow is just one command: `./gradlew nativeRun`.

In the real-world scenario, your application will, most likely, call either Java Reflection, Dynamic Proxy objects, or call some native code, or access classpath resources - the dynamic features which the `native-image` tool must be aware of at build time, and provided in the form of [metadata](../ReachabilityMetadata.md).
In the real-world, your application will, most likely, call either Java Reflection, Dynamic Proxy objects, or call some native code, or access resources on the class path - dynamic features that the `native-image` tool must be aware of at build time, and provided in the form of [metadata](../ReachabilityMetadata.md).
Native Image loads classes dynamically at build time, and not at run time.

Depending on your application dependencies, there could be three ways to provide the metadata with the Native Image Gradle Plugin:
Depending on your application dependencies, there are three ways to provide the metadata with the Native Image Gradle Plugin:

1. [Using the Tracing Agent](#build-a-native-executable-with-the-agent)
2. [Using the shared GraalVM Reachability Metadata Repository](#build-a-native-executable-using-the-graalvm-reachability-metadata-repository)
Expand Down

0 comments on commit 7b49365

Please sign in to comment.