skip to content

What is the GraalVM reachability-metadata repository and why does a native Spring Boot build need it?

level: juniorimportance: must knowfreq 60%

answer

  1. Closed-world analysis can't see reflection/resources/proxies
  2. Central JSON metadata keyed by group:artifact:version
  3. native-build-tools metadataRepository feature
  4. Spring Boot enables it by default
  5. Covers third-party jars, not your own code

basics

~20 s

It is a community-maintained collection of GraalVM native-image config (reflection, resources, proxies) for popular third-party libraries. The build tool pulls the right config so those libraries work in a native image without you writing hints by hand.

solid answer

~40 s

GraalVM's native-image compiler does closed-world static analysis: anything reached only via reflection, resources, JNI, dynamic proxies, or serialization is invisible to it and must be declared as 'reachability metadata'. Many third-party jars (drivers, JSON libs, etc.) need such metadata but don't ship it. The GraalVM reachability-metadata repository (github.com/oracle/graalvm-reachability-metadata) is a central, community-maintained store of that config, keyed by library coordinates and version. The GraalVM Native Build Tools plugin consumes it via its metadataRepository feature, so when your dependency graph includes a covered jar, the matching reflect-config/resource-config/etc. is added automatically. Spring Boot enables this by default, which is why many libraries 'just work' natively without hand-written RuntimeHints.

go deeper

for a junior

Should grasp that native image can't see reflection and that the repo supplies ready-made config for libraries.

for a middle

Should name the metadata categories and know Spring Boot enables it by default.

for a senior

Should distinguish it from RuntimeHints and reason about version matching.

for a principal

Should weigh coverage gaps, supply-chain/pinning, and contribution workflow.

## The problem GraalVM `native-image` compiles ahead-of-time under a *closed-world assumption*: it statically analyzes reachable code from `main` and includes only what it can prove is used. Dynamic behavior the analysis cannot see is invisible: - Java reflection (`Class.forName`, `Method.invoke`), - classpath resource loading, - JNI, - JDK dynamic proxies, - and serialization. If a class is instantiated only via reflection, native-image may strip it, causing runtime `ClassNotFoundException`/`NoSuchMethodException` or a missing resource. To fix this you supply **reachability metadata**: JSON files (`reflect-config.json`, `resource-config.json`, `proxy-config.json`, `serialization-config.json`, `jni-config.json`) telling the compiler to keep and register those elements. ## Why a repository Application code you own can declare hints, but you also depend on many third-party jars (JDBC drivers, Netty, Jackson, etc.) that use reflection internally. Hand-writing metadata for all of them is tedious and error-prone. The **GraalVM Reachability Metadata Repository** (`oracle/graalvm-reachability-metadata` on GitHub) is a central, open, community/vendor-maintained store of tested metadata organized per library by Maven coordinates (`group:artifact:version`). ## How it is consumed The **GraalVM Native Build Tools** (the `org.graalvm.buildtools.native` Gradle plugin / `native-maven-plugin`) has a `metadataRepository` feature. The plugin bundles a snapshot of the repository (and can fetch a specific version). During a native build it: 1. looks at your resolved dependencies, 2. finds matching metadata for their exact GAV coordinates, 3. and merges those JSON files into the native-image configuration automatically. **Spring Boot enables `metadataRepository` by default**, so covered libraries work natively with zero manual hints. ## Relationship to Spring hints This repository covers *third-party libraries*. For *your own* reflective code and for framework integration Spring uses its own `RuntimeHints` mechanism (`RuntimeHintsRegistrar`, `@ImportRuntimeHints`, `@RegisterReflectionForBinding`), emitted during AOT processing. The two are complementary: - the metadata repository handles libraries; - `RuntimeHints` handles your code and Spring's. ## When it helps / gotchas It only helps for libraries that: - (a) are in the repository and - (b) match your exact version — if a newer version has no entry, you get no metadata and may need your own hints or a fallback to an older covered version. It cannot cover truly application-specific dynamic behavior. Coverage is not universal, and metadata quality varies.

  • Name two kinds of dynamic behavior that reachability metadata declares.
    Any two of: reflection (classes/methods/fields), classpath resources, JDK dynamic proxies, serialization, JNI access.
  • Does the metadata repository replace Spring's RuntimeHints?
    No. The repository covers third-party libraries; RuntimeHints/RuntimeHintsRegistrar cover your own application and framework code. They work together.

context