Skip to content
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
83 changes: 45 additions & 38 deletions docs/reference-manual/native-image/ReachabilityMetadata.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ Computing metadata in code can be achieved in two ways:
return aClass;
}
}
```
```

When metadata is computed in code, the dynamically accessed elements will be included into the native executable's heap only if that part of the heap is reachable through an enclosing method (for example, `ReflectiveAccess#fetchFoo`) or a static field (for example, `InitializedAtBuildTime.aClass`).

Expand Down Expand Up @@ -89,6 +89,8 @@ A condition is specified in the following way:
An entry with a `typeReachable` condition is considered only when the fully-qualified class is reachable.
Currently, we support only `typeReachable` as a condition.

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

## Metadata Types

Native Image accepts the following types of reachability metadata:
Expand Down Expand Up @@ -144,8 +146,9 @@ Integer.class.getMethod("parseInt", params2);

### Specifying Reflection Metadata in JSON

Reflection metadata can be specified in the `reflect-config.json` file.
The JSON file is an array of reflection entries:
Reflection metadata should be specified in a _reflect-config.json_ file and conform to the JSON schema defined in
[reflect-config-schema-v1.0.0.json](https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/reflect-config-schema-v1.0.0.json).
The schema also includes further details and explanations how this configuration works. Here is the example of the reflect-config.json:
```json
[
{
Expand All @@ -162,12 +165,18 @@ The JSON file is an array of reflection entries:
"fields": [
{"name": "<fieldName>"}
],
"allDeclaredClasses": true,
"allDeclaredMethods": true,
"allDeclaredFields": true,
"allDeclaredFields": true,
"allDeclaredConstructors": true,
"allPublicClasses": true,
"allPublicMethods": true,
"allPublicFields": true,
"allPublicConstructors": true,
"allRecordComponents": true,
"allNestMembers": true,
"allSigners": true,
"allPermittedSubclasses": true,
"queryAllDeclaredMethods": true,
"queryAllDeclaredConstructors": true,
"queryAllPublicMethods": true,
Expand All @@ -177,21 +186,6 @@ The JSON file is an array of reflection entries:
]
```

The fields in a reflection entry have the following meaning:
- `condition`: See [Conditional Metadata Entries](#specifying-metadata-with-json)
- `name`: Name of the class that will be reflectively looked up. This property is mandatory.
- `methods`: List class methods that can be looked up and executed reflectively.
Each method is described by its name and a list of parameter types.
The parameter types are fully qualified Java class names.
- `queriedMethods`: List of class methods that can only be looked up.
The description of each method is identical to the `methods` list.
- `fields`: List of class fields that can be looked up, read, or modified.
- `all<access>(Methods/Fields/Constructors)`: Registers all methods/fields/constructors for lookup. Methods and constructors can also be invoked.
`<access>` refers to different ways of querying these members in Java and can be either `Declared` or `Public`.
For more information, see `java.lang.Class.getDeclaredMethods()` and `java.lang.Class.getPublicMethods()`.
- `queryAll<access>(Methods/Constructors)`: Registers all methods/constructors for lookup only.
- `unsafeAllocated`: Allows objects of this class to be allocated using `Unsafe.allocateInstance`.

## Java Native Interface

Java Native Interface (JNI) allows native code to access arbitrary Java types and type members.
Expand All @@ -213,8 +207,11 @@ The generated metadata entry for the above call would look like:
It is not possible to specify JNI metadata in code.

### JNI Metadata in JSON
Metadata for JNI is provided in `jni-config.json` files.
The JSON schema of JNI metadata is identical to the [Reflection metadata schema](#specifying-reflection-metadata-in-json).

JNI metadata should be specified in a _jni-config.json_ file and conform to the JSON schema defined in
[jni-config-schema-v1.0.0.json](https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/jni-config-schema-v1.0.0.json).
The schema also includes further details and explanations how this configuration works. The example of jni-config.json is the same
as the example of reflect-config.json described above.

## Resources and Resource Bundles
Java is capable of accessing any resource on the application class path, or the module path for which the requesting code has permission to access.
Expand All @@ -241,14 +238,17 @@ class Example {
```

### Resource Metadata in JSON
Metadata for resources is provided in `resource-config.json` files.

Resource metadata should be specified in a _resource-config.json_ file and conform to the JSON schema defined in
[resource-config-schema-v1.0.0.json](https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/resource-config-schema-v1.0.0.json).
The schema also includes further details and explanations how this configuration works. Here is the example of the resource-config.json:
```json
{
"resources": {
"includes": [
{
"condition": {
"typeReachable": "<condition-class>"
"typeReachable": "<condition-class>"
},
"pattern": ".*\\.txt"
}
Expand All @@ -269,15 +269,21 @@ Metadata for resources is provided in `resource-config.json` files.
},
"name": "fully.qualified.bundle.name",
"locales": ["en", "de", "sk"]
},
{
"condition": {
"typeReachable": "<condition-class>"
},
"name": "fully.qualified.bundle.name",
"classNames": [
"fully.qualified.bundle.name_en",
"fully.qualified.bundle.name_de"
]
}
]
}
```

Native Image will iterate over all resources and match their relative paths against the Java regex specified in `includes`.
If the path matches the regex, the resource is included.
The `excludes` statement instructs `native-image` to omit certain included resources that match the given `pattern`.

## Dynamic Proxy

The JDK supports generating proxy classes for a given interface list.
Expand Down Expand Up @@ -316,7 +322,10 @@ The following methods are evaluated at build time when called with constant argu
- `java.lang.reflect.Proxy.newProxyInstance`

### Dynamic Proxy Metadata in JSON
Metadata for dynamic proxies is provided in `proxy-config.json` files.

Dynamic proxy metadata should be specified in a _proxy-config.json_ file and conform to the JSON schema defined in
[proxy-config-schema-v1.0.0.json](https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/proxy-config-schema-v1.0.0.json).
The schema also includes further details and explanations how this configuration works. Here is the example of the proxy-config.json:
```json
[
{
Expand Down Expand Up @@ -366,7 +375,10 @@ To create a custom constructor for serialization use:
Proxy classes can only be registered for serialization via the JSON files.

### Serialization Metadata in JSON
Metadata for serialization is provided in `serialization-config.json` files.

Serialization metadata should be specified in a _serialization-config.json_ file and conform to the JSON schema defined in
[serialization-config-schema-v1.0.0.json](https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/serialization-config-schema-v1.0.0.json).
The schema also includes further details and explanations how this configuration works. Here is the example of the serialization-config.json:
```json
{
"types": [
Expand Down Expand Up @@ -397,12 +409,6 @@ Metadata for serialization is provided in `serialization-config.json` files.
}
```

Each entry in `types` enables serializing and deserializing objects of the class given by `name`.

Each entry in `lambdaCapturingTypes` enables lambda serialization: all lambdas declared in the methods of the class given by `name` can be serialized and deserialized.

Each entry in `proxies` enables the [Proxy](https://docs.oracle.com/javase/8/docs/technotes/guides/reflection/proxy.html) serialization by providing an interface list that a proxy implements.

## Predefined Classes

Native Image requires all classes to be known at build time (a "closed-world assumption").
Expand All @@ -418,7 +424,10 @@ At runtime, if there is an attempt to load a class with the same name and byteco
It is not possible to specify predefined classes in code.

### Predefined Classes Metadata in JSON
Metadata for predefined classes is provided in `predefined-classes-config.json` files.

Predefined classes metadata should be specified in a _predefined-classes-config.json_ file and conform to the JSON schema defined in
[predefined-classes-config-schema-v1.0.0.json](https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/predefined-classes-config-schema-v1.0.0.json).
The schema also includes further details and explanations how this configuration works. Here is the example of the predefined-classes-config.json:
```json
[
{
Expand All @@ -433,8 +442,6 @@ Metadata for predefined classes is provided in `predefined-classes-config.json`
]
```

The JSON schema is accompanied by the `agent-extracted-predefined-classes` directory that contains the bytecode of the listed classes.

### Further Reading

* [Metadata Collection with the Tracing Agent](AutomaticMetadataCollection.md)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,190 @@
{
"$schema": "https://json-schema.org/draft/2019-09/schema",
"$id": "https://github.com/oracle/graal/blob/master/docs/reference-manual/native-image/assets/jni-config-schema-v1.0.0.json",
"default": [],
"items": {
"properties": {
"condition": {
"properties": {
"typeReachable": {
"type": "string",
"title": "Fully qualified class name of the class that must be reachable in order to register the class <name> for access through JNI"
}
},
"required": [
"typeReachable"
],
"additionalProperties": false,
"type": "object"
},
"name": {
"type": "string",
"title": "Name of the class that should be registered for access through JNI"
},
"methods": {
"default": [],
"items": {
"properties": {
"name": {
"type": "string",
"title": "Method name that should be registered for this class"
},
"parameterTypes": {
"default": [],
"items": {
"type": "string",
"title": "List of types for the parameters of the this method"
},
"type": "array"
}
},
"required": [
"name"
],
"additionalProperties": false,
"type": "object",
"title": "List of methods from this class that are registered for access through JNI"
},
"type": "array",
"title": "List of methods that should be registered for the class declared in <name>"
},
"queriedMethods": {
"default": [],
"items": {
"properties": {
"name": {
"type": "string",
"title": "Method name that are queried for this class"
},
"parameterTypes": {
"default": [],
"items": {
"type": "string",
"title": "List of types for the parameters of the this method"
},
"type": "array",
"title": "List of methods to register for this class that are only looked up but not invoked."
}
},
"required": [
"name"
],
"additionalProperties": false,
"type": "object"
},
"type": "array",
"title": "List of methods that are queried for the class declared in <name>"
},
"fields": {
"default": [],
"items": {
"properties": {
"name": {
"type": "string",
"title": "Name of the field that should be registered for access through JNI"
}
},
"required": [
"name"
],
"additionalProperties": false,
"type": "object"
},
"type": "array",
"title": "List of fields that should be registered for the class declared in <name>"
},
"allDeclaredClasses": {
"default": false,
"type": "boolean",
"title": "Register classes which would be returned by the java.lang.Class#getDeclaredClasses call"
},
"allDeclaredMethods": {
"default": false,
"type": "boolean",
"title": "Register methods which would be returned by the java.lang.Class#getDeclaredMethods call"
},
"allDeclaredFields": {
"default": false,
"type": "boolean",
"title": "Register fields which would be returned by the java.lang.Class#getDeclaredFields call"
},
"allDeclaredConstructors": {
"default": false,
"type": "boolean",
"title": "Register constructors which would be returned by the java.lang.Class#getDeclaredConstructors call"
},
"allPublicClasses": {
"default": false,
"type": "boolean",
"title": "Register all public classes which would be returned by the java.lang.Class#getClasses call"
},
"allPublicMethods": {
"default": false,
"type": "boolean",
"title": "Register all public methods which would be returned by the java.lang.Class#getMethods call"
},
"allPublicFields": {
"default": false,
"type": "boolean",
"title": "Register all public fields which would be returned by the java.lang.Class#getFields call"
},
"allPublicConstructors": {
"default": false,
"type": "boolean",
"title": "Register all public constructors which would be returned by the java.lang.Class#getConstructors call"
},
"allRecordComponents": {
"default": false,
"type": "boolean",
"title": "Register record components which would be returned by the java.lang.Class#getRecordComponents call"
},
"allPermittedSubclasses": {
"default": false,
"type": "boolean",
"title": "Register permitted subclasses which would be returned by the java.lang.Class#getPermittedSubclasses call"
},
"allNestMembers": {
"default": false,
"type": "boolean",
"title": "Register nest members which would be returned by the java.lang.Class#getNestMembers call"
},
"allSigners": {
"default": false,
"type": "boolean",
"title": "Register signers which would be returned by the java.lang.Class#getSigners call"
},
"queryAllDeclaredMethods": {
"default": false,
"type": "boolean",
"title": "Register methods which would be returned by the java.lang.Class#getDeclaredMethods call but only for lookup"
},
"queryAllDeclaredConstructors": {
"default": false,
"type": "boolean",
"title": "Register constructors which would be returned by the java.lang.Class#getDeclaredConstructors call but only for lookup"
},
"queryAllPublicMethods": {
"default": false,
"type": "boolean",
"title": "Register all public methods which would be returned by the java.lang.Class#getMethods call but only for lookup"
},
"queryAllPublicConstructors": {
"default": false,
"type": "boolean",
"title": "Register all public constructors which would be returned by the java.lang.Class#getConstructors call but only for lookup"
},
"unsafeAllocated": {
"default": false,
"type": "boolean",
"title": "Allow objects of this class to be instantiated with a call to jdk.internal.misc.Unsafe#allocateInstance"
}
},
"required": [
"name"
],
"additionalProperties": false,
"type": "object"
},
"type": "array",
"title": "JSON schema for the jni-config that GraalVM Native Image uses"
}
Loading