graal
graal copied to clipboard
[GR-58477] Reduce the complexity of Native Image reachability metadata
This issue aims to evaluate various methods to reduce the size of the current reachability metadata required for Native Image, specified in reachability-metadata.json
files. The tradeoff when reducing metadata size is often an increase in image size, so this evaluation will seek to determine whether the changes proposed below have an acceptable impact on image size for the benefits they bring. To do so, we will look at the impact on the various libraries in the graalvm-reachability-metadata repository and the major microservice frameworks using Native Image.
Here is a summary of the current format of reachability-metadata.json
:
{
"reflection": [
{
"type": "reflectively.accessed.Type",
"fields": [
{
"name": "field1"
}
],
"methods": [
{
"name": "method1",
"parameterTypes": []
}
],
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"unsafeAllocated": true,
}
],
"jni": [
{
"type": "reflectively.accessed.Type",
"fields": [
{
"name": "field1"
}
],
"methods": [
{
"name": "method1",
"parameterTypes": []
}
],
"allDeclaredConstructors": true,
"allPublicConstructors": true,
"allDeclaredFields": true,
"allPublicFields": true,
"allDeclaredMethods": true,
"allPublicMethods": true,
"unsafeAllocated": true,
}
],
"resources": [
{
"module": "optional.module.of.a.resources",
"glob": "path1/level*/**"
}
],
"bundles": [
{
"name": "fully.qualified.bundle.name",
}
],
"serialization": [
{
"type": "serialized.Type",
"customTargetConstructorClass": "serialized.super.Type"
}
]
}
Include all resources from program JARs
Native Image currently needs to know the URL of every resource potentially accessed at run-time by the program. These resources can come from two sources:
- Files from the user file system unrelated with the program: these files should not be required in the resource metadata and simply be allowed to be accessed at run-time. This can be achieved at no image size cost.
- Resources from program JARs: The Native Image builder needs to know these at build-time. Removing these from the reachability metadata means that we include all resources from program JARs in the image. We will evaluate what is the impact of this change on image size.
Include all methods if one method is included
It is already possible to access elements of classes registered for reflection via query methods on Class
like getMethods()
or getDeclaredField()
when the type is registered for reflection (see #3566). However, the Method
, Field
and Constructor
objects obtained in this way do not support reflective access (e.g. Method.invoke()
or Field.set()
) as these capabilities potentially lead to a big increase in reachable code, and therefore image size. We will however investigate whether including all methods and constructors for reflective invocation if one method or constructor is already registered (i.e. changing method reflection metadata to a single boolean choice) yields acceptable image size increases for the reduction in metadata it allows.
Testing on the metadata repository showed a mean image size increase of 2.5% (max. 100%) when registering one method registers all methods of a type for reflection.
Enable all fields to be reflectively accessed by default
Whereas including methods for reflection can have an important impact on reachability, including fields is typically less of an issue. We will investigate whether enabling reflective access for fields of registered types and removing the "all[Public|Declared]Fields"
fields in the reachability metadata JSON files causes a significant image size increase.
Testing on the metadata repository shows a mean image size increase of 0.3% (max. 2.3%) when fields are reflectively accessed by default.
Consider all reflectively accessed types as unsafe allocated, accessed through JNI, and/or serializable
We will evaluate whether removing the "unsafeAllocated"
JSON field or the "jni"
or "serializable"
objects in reachability metadata significantly affects image size which, along with the resource changes proposed above and the potential integration of resource bundles in the reflection metadata, could reduce reachability metadata to a single set of types, thus greatly simplifying it.
Testing on the metadata repository shows a mean image size increase of 0,4% (max. 3.2%) when all types are registered as unsafe allocated, 0,4% (max. 5.3%) when all methods and fields are registered for JNI, and 0.2% (max 0.4%) when all types are registered for serialization.
Always register all super constructors of serializable types
Serialization metadata currently requires a custom super constructor class to be specified if a non-default constructor is expected to be used. We will evaluate the impact of including all super constructors from serializable classes, thus removing this requirement.
Testing on the metadata repository shows a mean image size increase of 0,2% (max 0.4%) when all super constructors of serializable types are registered.