Native Image Committer and Community Meeting 2025-01-30 #10546
Unanswered
wirthi
asked this question in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
List of all past and upcoming meetings: #3933
The meeting after this one is planned for February 27th, 2025. The meeting will typically be on the last Thursday of each month.
New and Noteworthy
JDK 24 is feature complete
Native Image Layers
[GR-60565] Move non-critical DynamicHub fields to companion object. #10495
[GR-57350] Make resources layer aware #10501
[GR-59148] Read JNI dictionary from all layers. #10456
[GR-61279] Fixes for various linkage errors. #10482
[GR-59590] Reduce vtable slots in application layer. #10544
[GR-60710] Encode numClassTypes in DynamicHub.typeIDDepth. #10378
[GR-57640] Do not allow ImageSingletons.lookup to be called on MultiLayeredImageSingletons. #10533
[GR-61459] Ensure objects are not modified while graphs are persisted #10528
[GR-59783] Change MultiLayerImageSingleton array properties. #10519
[GR-60740] [GR-61079] Refactor field inclusion policy in base layer and improve name checks mechanism. #10507
[GR-60551] [GR-60503] Mark all persisted constants as reachable #10502
[GR-49858] [GR-60710] In DynamicHub, use byte for hubType and short for open-world type information. #10462
[GR-60685] Refactor UnsupportedFeatures reporting. #10430
[GR-60640] Expose CapnProtoSchemaHolder to ImageLayerSingletons. #10418
[GR-60500] Refactor ImageLayerWriter/Loader #10414
[GR-60631] Always copy over relocatable section for layered images. #10404
[GR-60604] Improve causality reporting for unresolved elements. #10401
[GR-57832] [GR-59694] Load strengthened graph early #10361
[GR-60601] Fix persiting enum values in annotations #10347
[GR-60508] Include more information in the hash of method handle invoker substitution names #10324
[GR-60093] Keep existing speciesData objects in cache at run-time #10454
GuestGraal / LibGraal
[GR-60088] Add org.graalvm.nativeimage.libgraal module. #10380
Streamline reachability metadata
Usability
[GR-50683] Initialize most of java.xml at run time. #10537
[GR-49525] Mechanism to move JDK initialization to run time. #10531
[GR-58490] Adapt PartialConfigurationWithOrigins to reachability-metadata.json #10423
[GR-54978] [GR-59135] Report unrecognized/ill-formed hosted options in NI driver. #10485
Monitoring / tools
[GR-61151] Trim internal JFR stacktraces to match OpenJDK #10385 (Red Hat)
Debugging
[GR-54697] Implement debuginfo generation at image-runtime. #10522
[GR-58574] Add SVM interpreter and JDWP support for Native Image #10344
FFM API / Panama
[libgraal] Failed to build graalVM. #10388
[GR-60395] Allow combination of captureCallState and critical(true). #10301
Other
[GR-60457] [GR-52400] Revise heuristic for memory usage of Native Image build process. #10441
[GR-61342] Move SVM style gate to JDK latest #10483 (towards removal of JDK21 from master)
Rerun
sun.nio.ch.NioSocketImpl
class initializer #10431 (Red Hat)[GR-59749] Use a contiguous address space for the Native Image Java heap. #10323
Questions
Deep Dive: Evolution of reachability metadata
This document presents the remaining open questions about the future of Native Image reachability metadata, and the current state of their evaluation and implementation.
Which exception do we throw on missing registrations?
Native Image behavior in the presence of reflective access to unregistered elements has gone through several phases. For GraalVM for JDK 25, we would like to select the best way to handle these cases from both the perspective of the user and of Native Image debugging.
The need to handle missing registrations in a Native Image-specific way arises from the fact that otherwise the following code snippets have the same behavior:
In particular, the following situation can occur, which is a common occurrence in user code:
Without Native Image-specific handling of missing registrations, the code for the previous JDK would be executed even on the new JDK if the reflection registration is missing, without the user being aware that the execution branched off from the expected path, potentially leading to hard-to-debug issues down the line.
Before: Regular JDK exception (
ClassNotFoundException
)The original way Native Image handled class names and members it didn't know about was to consider they didn't exist, and throw the corresponding JDK exception.
Advantages
Drawbacks
ClassNotFoundException
, it is impossible to know whether the class hasn't been registered, or indeed doesn't exist. A debugging mode would require a data structure holding the names of all classes on the class path;catch (ClassNotFoundException e)
Now: Custom Native Image error (
MissingReflectionRegistrationError
)To solve the problems detailed above, we introduced Native Image-specific errors which are thrown on reflective queries for unregistered classes or elements, regardless of whether it exists. This error is currently hidden behind the
--exact-reachability-metadata
flag, which we plan to enable by default in GraalVM for JDK 25. Throwing a Native Image-specificError
was intended to make it as hard as possible to ignore such an occurrence and force users to adapt their reachability metadata immediately.Advantages
catch (Throwable t)
orcatch (Error e)
;Drawbacks
Compromise: Subclass existing JDK exception/error
In order to keep the advantages of throwing a distinct exception for missing registrations while enabling users to keep some flexibility in their usage of reachability metadata, we are proposing to make missing registration errors a subclass of a JDK class.
The choice of this JDK class can be one of many:
ClassNotFoundException
or similar: Keeps the silencing problem of the initial Native Image behavior;ReflectiveOperationException
: Impossible unless we change the JDK, as it is a checked exception;RuntimeException
: Can be used, but implies "normal execution" which is not what we want to convey;LinkageError
: Can be thrown without modifying the signature and can be caught by the user, but it has to be explicitly handled.We propose to use
LinkageError
as superclass of missing registration errors.Advantages
Mitigation
Compromise 1: Include all metadata and keep the flag
--exact-reachability-metadata
for debuggingAdvantages
Disadvantage: An additional mode for debugging
How can we simplify reachability-metadata.json?
A common complaint we receive from users is the complexity and time-consuming nature of creating reachability metadata for their workloads. We have started to simplify the structure of reachability-metadata.json in order to make it as straightforward to use as possible. We are aiming to limit the schema from the following structure:
To the simplified structure below:
The simplifications required to achieve this goal are detailed in the following sections.
Negative queries
A registration is currently required for queries which are expected to return a JDK exception (such as a
ClassNotFoundException
) at run-time. The following example:only works on Native Image with the following reachability metadata:
Keeping track of these negative queries is a regular source of complaints from users due to the time it requires to gather them, especially for specific code patterns which use multiple
Class.forName
calls to eventually find the expected result.Reflection
Negative queries are currently used for the following reflective queries:
reachability-metadata.json
format since all elements from a reflectively-accessible class are known at run-time.An alternative would be to store all class names in the classpath in a heap data structure and check it at run-time
If the class is registered, we return it
Else if the class name is present in the data structure, we throw a missing registration error (we know it's missing)
Else, we throw a
ClassNotFoundException
(we know it doesn't exist)This data structure makes negative queries unnecessary, which is a big usability benefit with an image size cost.
We evaluated the image size impact of such a data structure by using the
CompressedGlobTrie
that we already use to handle glob resource queries at run-time on helloworld and the microservice benchmarks. It results in a significant image size increase when including all classes in the class path (from 12% to 200%). Excluding Graal classes and JDK classes results in an acceptable increase for helloworld (<1%), but is still significant for the microservices (4% to 10% increase).This optimization can therefore probably not be enabled by default in the general case, but could be provided as an option for workflows requiring a big number of negative queries.
Resources
When excluding class files, the size of a data structure including all resources on the class path is smaller than the class name data structure. The following graph shows the image size impact of including such a structure, both with and without class files.
Such a structure would have the added benefit of allowing users to freely navigate the resource file system without configuration, which is a very demanded feature.
Custom constructors serialization
The
"customConstructorClass"
field for serializable types has already been deprecated. All possible custom constructors are now automatically registered for run-time serialization. The image size impact of the change has been evaluated to be minimal, as this only concerns a few constructors for certain classes.Image size impact: #9679
"serializable"
flagThe "serialization" section of
reachability-metadata.json
has already been deprecated and replaced by the"serializable"
flag in the"reflection"
section.There is no impact on the image size as serialization already implies reflective access.
As a result of the two serialization changes presented above, the following
reachability-metadata.json
file:is now equivalent to the previously required:
Unsafe allocation
The removal of the
"unsafeAllocated"
field for reflectively-accessible types in currently being evaluated. The main issue with this change is that considering all reflectively-accessed types as unsafe allocatable makes the analysis less precise, which could result in performance issues.Testing performed on the CI for this change shows no significant regression.
If this change is accepted, the following reachability-metadata.json file:
will be equivalent to the currently required:
Field registration
Including all fields of reflectively-accessible types as accessed is currently being evaluated. A potential issue is that making more fields reachable can drag large quantities of unused data into the image heap if they are initialized at build-time, as happens on Quarkus (10% image size increase with this change).
Testing performed on the CI for this change shows no significant regression.
To mitigate the problem, field registration options could be left as an opt-out for advanced users when such an image size increase occurs.
If this change is accepted, the following reachability-metadata.json file:
will be equivalent to the currently required:
"jniAccessible"
flagGetting rid of the
"jni"
section ofreachability-metadata.json
requires the following changes to the"reflection"
section:Registering a type for run-time reflective access should make the type accessible through JNI as well. This change only requires a small data structure to be included in the image for each type and has a limited image size impact.
We need to add a
"jniAccessible"
flag to reflectively-accessed method declarations. This has the side effect of making any JNI-accessible method reflectively-accessible as well, but this causes only a very limited image size increase.The following graph shows the image size impact of these changes, as well as the increase should the
"jniAccessible"
flag be omitted. The results speak in favor of including JNI as part of reflection registration with a flag for methods, at least until we can reduce the impact of including methods for JNI access in the image.If this change is accepted, the following reachability-metadata.json file:
will be equivalent to the currently required:
Resource bundles
We are currently investigating whether resource bundle registration could be included in the "reflection" and "resources" sections of reachability-metadata.json, since bundles can either be subclasses of ResourceBundle or based on property files.
Beta Was this translation helpful? Give feedback.
All reactions