Skip to content

Commit

Permalink
Address review comments round 2
Browse files Browse the repository at this point in the history
  • Loading branch information
olyagpl authored and vjovanov committed Sep 17, 2024
1 parent e9d7e8e commit c1807ab
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 19 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ The option can be specified more than once to add multiple filter files and can
### Specify Configuration Files as Arguments

A directory containing configuration files that is not part of the class path can be specified to `native-image` via `-H:ConfigurationFileDirectories=/path/to/config-dir/`.
This directory must directly contain _reachability-metadata.json_ or legacy files _jni-config.json_, _reflect-config.json_, _proxy-config.json_, _serialization-config.json_, and _resource-config.json_.
This directory must directly contain _reachability-metadata.json_ or the formerly-used individual metadata files (_jni-config.json_, _reflect-config.json_, _proxy-config.json_, _serialization-config.json_, and _resource-config.json_).
A directory with the same metadata files that is on the class path, but not in `META-INF/native-image/`, can be provided via `-H:ConfigurationResourceRoots=path/to/resources/`.
Both `-H:ConfigurationFileDirectories` and `-H:ConfigurationResourceRoots` can also take a comma-separated list of directories.

Expand Down
2 changes: 1 addition & 1 deletion docs/reference-manual/native-image/JNI.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ This requires keeping the necessary metadata for these lookups around.
The `native-image` builder must know beforehand which items will be looked up in case they might not be reachable otherwise and therefore would not be included in a native image.
Moreover, `native-image` must generate wrapper code ahead-of-time for any method that can be called via JNI.
Therefore, specifying a concise list of items that need to be accessible via JNI guarantees their availability and allows for a smaller footprint.
Such a list should be specified in [`reachability-metadata.json` files](ReachabilityMetadata.md#java-native-interface).
Such a list should be specified in the [_reachability-metadata.json_ file](ReachabilityMetadata.md#java-native-interface).

The JNI configuration can be collected automatically using the [Tracing Agent](AutomaticMetadataCollection.md) from the GraalVM JDK.
The agent tracks all usages of dynamic features during application execution on a regular Java VM.
Expand Down
33 changes: 19 additions & 14 deletions docs/reference-manual/native-image/ReachabilityMetadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ redirect_from:

# Reachability Metadata

The dynamic language features of the JVM (for example, reflection and resource handling) compute the *dynamically-accessed program elements* such as fields, methods, or resource URLs at runtime.
The dynamic language features of the JVM (for example, reflection and resource handling) compute the *dynamically-accessed program elements* such as fields, methods, or resource URLs at run time.
On HotSpot this is possible because all class files and resources are available at run time and can be loaded by the runtime.
Availability of all classes and resources, and their loading at run time, comes with an extra overhead in memory and startup time.

To make native binaries small, the `native-image` builder performs [static analysis](NativeImageBasics.md#static-analysis-reachability-and-closed-world-assumption) at build time to determine only the necessary program elements that are needed for the correctness of the application.
Small binaries allow fast application startup and low memory footprint, however they come at a cost: determining dynamically-accessed application elements via static analysis is infeasible as reachability of those elements depends on data that is available *only* at run time.

To ensure inclusion of necessary dynamically-accessed elements into the native binary, the `native-image` builder requires **reachability metadata** (in further text referred as *metadata*).
To ensure inclusion of necessary dynamically-accessed elements into the native binary, the `native-image` builder requires **reachability metadata** (hereinafter referred to as *metadata*).
Providing the builder with correct and exhaustive reachability metadata guarantees application correctness and ensures compatibility with third-party libraries at runtime.

Metadata can be provided to the `native-image` builder in the following ways:
Expand All @@ -42,7 +42,7 @@ The application will then unconditionally print the error message with the stack
* [Computing Metadata in Code](#computing-metadata-in-code)
* [Specifying Metadata with JSON](#specifying-metadata-with-json)
* [Metadata Types](#metadata-types)
* [Reflection (including dynamic proxies)](#reflection)
* [Reflection (Including Dynamic Proxies)](#reflection)
* [Java Native Interface](#java-native-interface)
* [Resources](#resources)
* [Resource Bundles](#resource-bundles)
Expand All @@ -54,7 +54,7 @@ The application will then unconditionally print the error message with the stack

Computing metadata in code can be achieved in two ways:

1. By providing *constant* arguments to functions that dynamically access elements of the JVM. See, for example, `Class#forName` in the following code
1. By providing *constant* arguments to functions that dynamically access elements of the JVM. See, for example, `Class#forName` in the following code:

```java
class ReflectiveAccess {
Expand Down Expand Up @@ -143,7 +143,8 @@ For example, Java reflection metadata is specified under `reflection`, and an ex
```
### Conditional Metadata Entries
Each entry in JSON-based metadata should be *conditional* to avoid unnecessary growth in the native-binary size.
Each entry in JSON-based metadata should be *conditional* to avoid unnecessary growth of the native binary size.
A conditional entry is specified by adding a `condition` field to the entry in the following way:
```json
{
Expand All @@ -158,8 +159,8 @@ A metadata entry with a `typeReached` condition is considered available at run t
Before that, all dynamic accesses to the element represented with the `metadata-entry` will behave as if the `metadata-entry` does not exist.
This means that those dynamic accesses will throw a missing-registration error.
A type is reached at run time, right before [class-initialization routine](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5) starts for that type (class or interface), or any of the type's subtypes are reached.
For `"typeReached": "ConditionType"` that guards a metadata entry, in the following example we can see where the type is considered reached:
A type is reached at run time, right before the [class-initialization routine](https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5) starts for that type (class or interface), or any of the type's subtypes are reached.
For `"typeReached": "ConditionType"` that guards a metadata entry in the following example, the type is considered reached:
```java
class SuperType {
static {
Expand Down Expand Up @@ -187,10 +188,10 @@ public class App {

A type is also reached, if it is marked as `initialize-at-build-time` or any of its subtypes are marked as `initialize-at-build-time` and they exist on the classpath.

Array types are never marked as reached and as such can not be used in conditions.
Array types are never marked as reached and as such cannot be used in conditions.

A conditional metadata entry is included into the image (at build time) when the fully-qualified type is reachable at build time.
This entry will affect the image size, however the entry will be available at run time only when the condition is reached at run time.
A conditional metadata entry is included into the image when the fully-qualified type is reachable at build time.
This entry affects the image size, and it will be available at run time only when the condition is reached at run time.

You can find more examples of the metadata files in the [GraalVM Reachability Metadata repository](https://github.com/oracle/graalvm-reachability-metadata).

Expand All @@ -206,7 +207,7 @@ Native Image accepts the following types of reachability metadata:

## Reflection

For all methods in this section Native Image will try to compute reachability at build-time given all the call arguments are constant.
For all methods in this section Native Image will compute reachability at build time given that all the call arguments are constant.
Providing constant arguments in code is a preferred way to provide metadata as it requires no duplication of information in external JSON files.

Reflection in Java starts with `java.lang.Class` that allows fetching further reflective elements such as methods and fields.
Expand Down Expand Up @@ -260,13 +261,14 @@ The following methods on `java.lang.Class` will throw a `MissingRegistrationErro
* `Class[] getClasses()`
* `Class[] getDeclaredClasses() throws SecurityException`

Furthermore, all reflective lookups via `java.lang.invoke.MethodHandles.Lookup` will also require metadata for the type to be present, or they will throw a `MissingReflectionRegistrationError`.
Furthermore, all reflective lookups via `java.lang.invoke.MethodHandles.Lookup` will also require metadata for the type to be present, or they will throw `MissingReflectionRegistrationError`.

Note that for lambda-proxy classes, metadata can not be provided.
This is a [known issue](https://github.com/oracle/graal/issues/7476) that will be addressed in the future releases of GraalVM.

### Reflective Method Invocation
To reflectively invoke methods the method signature must be added to the `type` metadata:

To reflectively invoke methods, the method signature must be added to the `type` metadata:
```json
{
"type": "TypeWhoseMethodsAreInvoked",
Expand Down Expand Up @@ -297,6 +299,7 @@ In case the method-invocation metadata is missing, the following methods will th
* `java.lang.invoke.MethodHandle#invokeWithArguments` (all overloaded versions)

### Reflective Field-Value Access

To reflectively access (get or set) field values, metadata about field names must be added to the type:
```json
{
Expand Down Expand Up @@ -703,7 +706,9 @@ The schema also includes further details and explanations how this configuration
]
```

## Sample _reachabilty-metadata.json_
## Sample ReachabilIty Metadata

See below is a sample reachabilIty metadata configuration that you can use in _reachabilty-metadata.json_:

```json
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ redirect_from:

# Configure Native Image with the Tracing Agent

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 metadata file or precompute metadata in the code.
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 a JSON-formatted metadata file or precompute metadata in the code.

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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ redirect_to: /reference-manual/native-image/metadata/#reflection
# Configure Dynamic Proxies Manually

You can generate dynamic proxy classes at build time by specifying the list of interfaces that they implement.
This can be done by adding a reflection entry in `reachability-metadata.json`. For example:
This can be done by adding a reflection entry in the _reachability-metadata.json_ configuration file. For example:

```json
{
Expand Down
2 changes: 1 addition & 1 deletion docs/security/JipherJCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ The steps below show how to embedded Jipher in a native executable, using a simp
It is recommended that the output directory is `/META-INF/native-image/` (if you build with Maven or Gradle, then `/resources/META-INF/native-image/`).
Later, when building a native executable, the `native-image` builder will pick up the files from that location automatically.

For this Java application, the agent creates `reachability-metadata.json`. The contents on Linux should be:
For this Java application, the agent creates the _reachability-metadata.json_ file with the following contents:
```json
{
"reflection":[
Expand Down

0 comments on commit c1807ab

Please sign in to comment.