- GraalVM Release Calendar
- GraalVM Community Edition 25
- GraalVM for JDK 24
- GraalVM for JDK 23
- GraalVM for JDK 22
- GraalVM for JDK 21
- GraalVM for JDK 20
- GraalVM for JDK 17
- GraalVM 22.3.x
- GraalVM 22.2.x
- GraalVM 22.1.x
- GraalVM 22.0.x
- GraalVM 21.3.x
- GraalVM 21.2.x
- GraalVM 21.1.x
- GraalVM 21.0.x
- GraalVM 20.3.x
- GraalVM 20.2.x
- GraalVM 20.1.x
- GraalVM 20.0.x
- GraalVM 19.3.x
GraalVM Community Edition 25
(2025-09-16)
- Platform and Distributions
- Availability of JDK 25 Features
- Graal Compiler
- Native Image
- GraalJS
- GraalPy
- GraalWasm
- Espresso
- Polyglot Runtime
- Truffle Framework
Platform and Distributions
- Released Oracle GraalVM 25 based on Oracle JDK 25. See Java SE 25 Release Notes.
- Released GraalVM Community Edition 25 based on OpenJDK 25. See OpenJDK 25 Updates.
-
- Oracle GraalVM is now available for Oracle Linux 10. Support for Oracle GraalVM on Oracle Linux 7 has ended. For setup instructions, see the installation guide.
- Version compatibility:
- Oracle GraalVM 25 is compatible with Graal Languages and other components version 25.0.0.
Features
- 470: PEM Encodings of Cryptographic Objects (Preview)
- 502: Stable Values (Preview)
- 503: Remove the 32-bit x86 Port
- 505: Structured Concurrency (Fifth Preview)
- 506: Scoped Values
- 507: Primitive Types in Patterns, instanceof, and switch (Third Preview)
- 508: Vector API (Tenth Incubator)
- 509: JFR CPU-Time Profiling (Experimental)
- 510: Key Derivation Function API
- 511: Module Import Declarations
- 512: Compact Source Files and Instance Main Methods
- 513: Flexible Constructor Bodies
- 514: Ahead-of-Time Command-Line Ergonomics
- 515: Ahead-of-Time Method Profiling
- 518: JFR Cooperative Sampling
- 519: Compact Object Headers
- 520: JFR Method Timing & Tracing
Graal Compiler
- Implemented initial optimization of Java Vector API (JEP 338) operations. Load, store, basic arithmetic, reduce, compare, and blend operations are transformed to efficient machine instructions where possible. Coverage of more operations is planned for the future. This optimization is experimental and can be disabled by setting the
OptimizeVectorAPI
option tofalse
. Vector API operations are supported both on JIT and when building native images.
Native Image
Performance Improvements
- Enabled Whole-Program Sparse Conditional Constant Propagation (WP-SCCP) by default, improving the precision of points-to analysis in Native Image. This optimization enhances static analysis accuracy and scalability, potentially reducing the size of the final native binary. Learn more about this optimization in SkipFlow: Producing Smaller Executables with GraalVM.
- Refined the Graal Neural Network (GraalNN) models for control split profile inference by introducing two specialized variants: a more conservative model for
O2
and a more aggressive one forO3
. These updates are expected to deliver performance improvements of 1–3% for bothO2
andO3
optimization levels, as well as a binary size reduction of over 1% inO2
. The new GNN-based control split profile inference is enabled by default inO3
. To enable it inO2
, pass the option-H:+MLProfileInferenceUseGNNModel
. - Added an XGBoost-based static profiler for call count profile inference in Native Image. The model classifies methods as either cold or regular/hot, guiding optimizations and reducing binary size with minimal impact on runtime performance. To enable it, use the option:
-H:+MLCallCountProfileInference
. Not available in GraalVM Community Edition. - Added the experimental option
-H:+RelativeCodePointers
to significantly reduce relocation entries in position-independent executables and shared libraries.
New Features
- Enhanced support for the Foreign Function & Memory (FFM) API (JEP 454) in Native Image:
- Platform compatibility – Enabled FFM API (“Panama”) support on macOS AArch64 and Linux AArch64.
- Introduced a new syntax for configuring the FFM API.
- Implemented
Arena.ofShared()
from the FFM API. - Added the Tracing agent support for applications using the FFM API. The agent generates the FFM configuration in the reachability-metadata.json file. Additionally, support for FFM configurations has been added to the
native-image-configure
tool. - Added extensive reference documentation for FFM API support in Native Image.
- Implemented initial optimization support of Java Vector API JEP 338 operations in native images. To enable these optimizations, build native images with the
--add-modules jdk.incubator.vector
and-H:+VectorAPISupport
options. - Introduced
--future-defaults=[all|run-time-initialize-jdk|<options>|none]
, which enables options planned to become defaults in future releases. The enabled options are:run-time-initialize-jdk
– Shifts from build-time initialization of the JDK to runtime initialization for most components. This transition is gradual, with different JDK components becoming runtime initialized in each release. In this release, it enablesrun-time-initialize-security-providers
andrun-time-initialize-file-system-providers
. If JDK classes are not stored in the image heap, this option should have no effect. If the option breaks your build, follow the suggestions in the error messages.complete-reflection-types
– Ensures that reflective registration of a type (via metadata files or the Feature API) always includes all type metadata. All registered types now behave consistently with types defined in the reachability-metadata.json file.run-time-initialize-security-providers
– Shifts from build-time initialization of security providers to runtime initialization. Unlessjava.security.Provider
-related classes are stored in the image heap, this option should have no effect. If it breaks your build, follow the suggestions in the error messages. Run-time initialization of security providers helps reduce image heap size by avoiding unnecessary objects inclusion.run-time-initialize-file-system-providers
– Shifts from build-time initialization ofjava.nio.file.spi.FileSystemProvider
to runtime initialization. UnlessFileSystemProvider
-related classes are stored in the image heap, this option should have no effect. If it breaks your build, follow the suggestions in the error messages.
- Enabled
--install-exit-handlers
by default for native executables and deprecated the option. If shared libraries were using this option, the same functionality can be restored by using the-H:+InstallExitHandlers
host option. - Recurring callback support is no longer enabled by default. To enable this feature, use the
-H:+SupportRecurringCallback
host option at image build time. - Added the experimental option
ClassForNameRespectsClassLoader
, which makesClass.forName(...)
respect the class loader hierarchy.
Improved Security
- Introduced advanced obfuscation for Native Image — an experimental Oracle GraalVM-only feature that applies symbol obfuscation to enhance protection against reverse engineering by renaming symbols in native images.
Advanced obfuscation affects user code and third party dependencies, but not JDK and GraalVM classes, or names required by reachability metadata, annotations, and proxies.
To enable the feature, pass
-H:AdvancedObfuscation=
to thenative-image
command. Learn more in the reference documentation. - A Software Bill of Materials (SBOM) is now embedded by default in native images. To disable the SBOM from being embedded, pass the option
--enable-sbom=false
. (Not available in GraalVM Community Edition).
Simplified Metadata Configuration
- Added the experimental option
-H:Preserve
to instruct thenative-image
tool to keep entire packages, modules, or all classes on the classpath. For example, if you pass-H:Preserve=package=<package_name>
, all of the classes in that package will be available in the native executable, even if static analysis could not discover them. The usage syntax is-H:Preserve=[all|none|module=<module>|package=<package>|package=<package-wildcard>|path=<cp-entry>][,...]
. See the example application for this use case. - JNI registration is now included as part of the
"reflection"
section in the reachability-metadata.json file using the"jniAccessible"
attribute. Registrations performed through the"jni"
section of reachability-metadata.json and through jni-config.json will still be accepted and parsed correctly. - Enabled lambda classes to be registered for reflection and serialization in the reachability-metadata.json file. The format is detailed here.
- Resource bundle registration is now included as part of the
"resources"
section in the reachability-metadata.json file. When this is the case, the bundle name is specified using the"bundle"
field. Find the examples in the documentation. - Missing registration errors are now subclasses of
LinkageError
. - Improved handling of invalid class names under
--exact-reachability-metadata
: Reflection and JNI queries now correctly throw the expected JDK exceptions without requiring metadata entries when the queried class name is clearly invalid.
Experimental Native Image Tracing Agent
- Added experimental support for a new Native Image Tracing Agent. Unlike the existing tracing agent (which observes application behavior on the JVM), the new agent operates in Native Image mode and is more closely aligned with Native Image semantics.
- To use the new agent, build your application with
-H:Preserve=all
(which also enables-H:+MetadataTracing
), and then run the executable with-XX:TraceMetadata=path=<trace_output_directory>
. - The agent will trace the actual types, resources, and other elements required by Native Image, and generate reachability metadata. This metadata can then be used to re-build the application with only the required types and resources.
- To use the new agent, build your application with
Platform Compatibility
- In containers and CI environments, the build process now uses 85% of system memory. Otherwise, it tries to only use available memory. If less than 8GB of memory are available, it falls back to 85% of system memory. The reason for the selected memory limit is now also shown in the build resources section of the build output.
Debugging and Monitoring Improvements
- Added support for the runtime debug info generation using the option
-H:+RuntimeDebugInfo
. It adds runtime debugging information into a native image for use with GDB. - Added a JVM version check to the Native Image agent. The agent now aborts execution if the JVM major version does not match the version it was built with and issues a warning if the full JVM version differs.
- Added validation of hosted options passed to
native-image
before starting the build process. Unknown options are detected early, with suggestions provided to help fix them. - Added the experimental
-H:+JDWP
option.
Deprecated Functionality
- Deprecated class-level metadata extraction using
native-image-inspect
and removed theDumpMethodsData
option. Instead, use class-level SBOMs by passing--enable-sbom=class-level,export
to thenative-image
builder. The default value of theIncludeMethodData
option has been changed tofalse
. - Removed the sequential reachability handler. The only remaining variant is the concurrent reachability handler, which has been the default implementation since its introduction. Additionally, the
-H:-RunReachabilityHandlersConcurrently
option was removed, which had been deprecated in GraalVM for JDK 24. - Removed the total number of loaded types, fields, and methods from the Native Image build output, deprecated these metrics in the build output schema, and removed already deprecated build output metrics.
- Jipher Java Cryptographic Service Provider (JCP) is no longer available as part of the Oracle GraalVM release, but can be downloaded separately from Java Tools and Resources. For more information, see the Jipher JCP reference documentation.
GraalJS
- Enabled ECMAScript 2025 mode by default.
- Made the option
js.text-encoding
stable and allowed inSandboxPolicy.CONSTRAINED
. - Enabled source phase imports from WebAssembly modules (
import source mod from "./mod.wasm"
) by default if thejs.webassembly
option is enabled, and thejs.source-phase-imports
option is not explicitly set tofalse
. - Implemented several ECMAScript proposals:
- Intl.DurationFormat
- Deferring Module Evaluation, available in ECMAScript staging mode (
--js.ecmascript-version=staging
) - Upsert, available in ECMAScript staging mode (
--js.ecmascript-version=staging
)
- Updated Node.js to version 22.17.1.
GraalPy
Improvements and New Features
- Updated the Python standard library and core to version 3.12.8.
- The full-featured Python REPL is now available on GraalPy standalone builds for Windows.
- The
sys.implementation.version
call now returns the GraalPy version instead of the Python version it implements. Additionally, the GraalPy version is available assys.graalpy_version_info
for easier discovery, especially by users familiar with PyPy’ssys.pypy_version_info
. - The
GRAALPY_VERSION_NUM
C macro now includes the release level and serial number to fully conform to thehexversion
format, without breaking existing version comparisons. - The
dir(foreign_object)
call now returns both foreign methods and Python methods, whereas previously it returned only foreign methods. - Added support for the
__name__
,__doc__
, and__text_signature__
attributes on foreign executables, enabling better integration with Python-side introspection. This is useful, for example, when using Java functional interfaces in place of Python functions—such as with LangChain’s@tool
annotation that inspects underlying functions. - Implemented
faulthandler.dump_traceback_later
to enhance support for testing frameworks that handle resilience to crashes. - Added support for sharing Arrow arrays and tables between Java, PyArrow, and Pandas, reducing data copying when embedding these libraries into Java projects.
- Enabled FTS3, FTS4, FTS5, RTREE, and math function features in the bundled SQLite3 library.
- Added compatibility patches for several libraries and versions, including Torch 2.7.0, PyGObject 3.52.3, xmlschema 4.0.0, lxml (below 5.4.0), SciPy 1.15, jq 1.8.0, NumPy (below 2.3), ormsgpack (below 1.9.1), pandas 2.2.3, PyArrow 19.0, and PyMuPDF 1.25.4.
Removed Functionality
- Removed support for running C extensions as LLVM bitcode. This also removes the related options
python.UseSystemToolchain
andpython.NativeModules
. Isolation of native code when embedding GraalPy into Java projects is now provided by the Oracle GraalVM polyglot isolate feature, which can launch in a separate external sub-process by setting the--engine.IsolateMode=external
option. - Removed the built-in HPy module. HPy can now be installed and used from its upstream sources.
Platform Compatibility
- Fixed several issues affecting
cibuildwheel
on Windows to make it easier for Python projects to build and distribute native extensions for GraalPy on all supported platforms. - The GraalPy Native standalone on Linux now uses the G1 garbage collector which is much faster.
GraalWasm
Context.eval
now returns a compiled (but not yet instantiated) module object, rather than a module instance. To instantiate the module, callnewInstance()
on the returned module object. For example:Context c = Context.create(); Source wasmSource = Source.newBuilder(...).build(); Value module = c.eval(wasmSource); Value instance = module.newInstance(); // prior to 25.0: c.eval(wasmSource)
- This change allows a single compiled module to be instantiated multiple times and run independently within the same context. Previously, each module could only be instantiated once per context.
- The
newInstance()
method optionally accepts an import object (similar to the WebAssembly JavaScript API), as well as other modules to link together. - To restore the previous behavior, pass the experimental option
--wasm.EvalReturnsInstance=true
to the builder. - Note that modules instantiated via
module.newInstance()
are not accessible throughcontext.getBindings("wasm")
, unlike modules instantiated directly usingcontext.eval
when the--wasm.EvalReturnsInstance=true
option is used.
- Exports are no longer exposed as direct members of the module instance.
Instead, use the exports member of the module instance to access its exports. For example:
Value mainFunction = instance.getMember("exports").getMember("main"); // prior to 25.0: instance.getMember("main")
This change aligns the API with the WebAssembly JavaScript API and makes it possible to introduce other members on the module instance without name clashes. For more details and migration examples, see the GraalWasm Polyglot API Migration Guide and the project README.
- Implemented support for editing primitive values during debugging. Fixed several debugger-related issues.
- Implemented the WebAssembly SIMD proposal using the JDK’s Vector API. This improves peak performance when running WebAssembly code that makes heavy use of SIMD instructions. The new implementation is always enabled in native images. On the JVM, it is opt-in and requires setting
--add-modules=jdk.incubator.vector
. Because the Vector API is incubating, enabling it will print the following warning to stderr:WARNING: Using incubator modules: jdk.incubator.vector
Espresso
- Added support for guest Java version 25.
- Added experimental support for
-javaagent
. The support forjava
agents helps integrate with various IDEs, debuggers, and so on. It can also be enabled via the Polyglot API by setting the optionjava.JavaAgent.$i
to/path/to/jar=agent-options
, where$i
starts at 0 and increments by 1 for each additional Java agent. - Added the
org.graalvm.continuations.IdentityHashCodes
class, which provides utilities to restore identity hash codes. This can be used to improve deserialization of continuations. - Introduced the
EnableAdvancedRedefinition
option, which controls whether features such as method or field addition/removal and class hierarchy changes are enabled. This option controls access to these capabilities for both JDWP and Java agents. Previously, this functionality was enabled by default for JDWP; in this release, it must now be explicitly turned on. - Added experimental support for JVMCI, which can be enabled with the
java.EnableJVMCI
option.
Polyglot Runtime
- All language and tool POMs artifacts are now OSS licensed. It means:
- The “community” Maven artifacts (those with an artifact ID ending in
-community
) are now identical to their corresponding “non-community” artifacts. - All community language and tool POM artifacts have been deprecated.
- The only exception is
org.graalvm.truffle:java-community
vs.org.graalvm.truffle:java
, which still differ in the bundled Java runtime. - Embedders using auxiliary engine caching, polyglot isolates, a isolated or untrusted sandbox policy, or the sandbox resource limits must now explicitly add the
org.graalvm.truffle:truffle-enterprise
Maven artifact to the classpath or module path.
- The “community” Maven artifacts (those with an artifact ID ending in
- Improved the memory isolation between multiple isolates, known as Monocle or Software Fault Isolation.
Monocle is a new mitigation for speculative execution attacks for runtime-compiled code running inside GraalVM isolates. With Monocle enabled, every load generated from untrusted code is either (a) masked so it cannot address memory outside its own isolate heap, or (b) guarded by a lightweight fence when masking is impossible. This keeps one isolate from speculatively reading data belonging to another isolate in the same GraalVM process. Monocle is about 4x faster compared to the previous, fence-based mitigation, while delivering the same security guarantees. It is available for the AMD64 architecture and can be enabled with
-R:+MemoryMaskingAndFencing
. Monocle is used for polyglot isolates. As a result, sandboxed code execution is faster. - The option
sandbox.MaxStackFrames
is no longer mandatory for theUNTRUSTED
polyglot sandbox policy, due to improved deoptimization handling in compiled code. Removing the option significantly improves performance of the sandboxed code. - The WebAssembly (Wasm) language is now available as a polyglot isolate under the name
wasm-isolate
on Maven Central. Wasm is now supported for untrusted code execution (all three are polyglot isolates related).
Find a complete list of updates in the changelog.
Truffle Framework
- Added the deoptimization cycle detection feature, which is enabled by default. When a deoptimization cycle is detected, the compilation fails with a permanent bailout that includes the Java stack trace of the problematic location. If this error is encountered too frequently it can be disabled by setting
compiler.DeoptCycleDetectionThreshold
to-1
. For further information, see the Automatic Detection of Deoptimization Cycles guide. - Implemented the extended Dynamic Object Model Layout that adds:
- A shape obsolescence strategy enabling optimistic type speculation for primitive property values. When speculation fails, shapes gradually migrate to more general forms (for example, moving primitive slots to reference slots), eventually converging on a stable, general shape tree. This reduces shape polymorphism by replacing overly specific shapes with more general ones.
- Automatic reference type tracking based on assumptions, which eliminates redundant type checks.
- Automatic single-assignment tracking based on assumptions allowing languages to assume that a property is effectively final (i.e. stays unchanged after the initial assignment) as well as constant-fold values of a constant receiver with a known shape.
- You can still disable the new layout and switch back to the previous implementation using the system property
-Dtruffle.object.LayoutFactory=com.oracle.truffle.api.object.CoreLayoutFactory
.
- Enabled lazy deoptimization of runtime-compiled code by default for native-image hosts, which reduces memory used for deoptimization. It can be turned off using the
-H:-LazyDeoptimization
option. - Now you can specify language and instrument specific options using
Source.Builder.option(String, String)
. Languages may describe available source options by implementing the methodsTruffleLanguage.getSourceOptionDescriptors()
andTruffleInstrument.getSourceOptionDescriptors()
respectively. - Added multiple improvements to Bytecode DSL:
- Improved builder performance: creating bytecode nodes is now 40% faster and requires five times less temporary memory.
- Builder instances now implement
toString()
, which prints both the current operations and the instructions already emitted. This should make debugging builder usage easier. - Improved variadic support: variadic operands now compile and execute more efficiently, with fewer reallocations.
- Added a
startOffset
parameter to@Variadic
, allowing reservation of a fixed number of slots in the object array for custom use. The@Variadic
annotation can now also be applied to@Operation
-annotated classes to indicate that the operation produces a dynamic variadic return value. Dynamic@Variadic
return values are efficiently flattened into the object array of a@Variadic
operand. - Added a
variadicStackLimit
parameter to@GenerateBytecode
that allows to specify how many variable arguments are stored on the stack before they are collapsed into an object array.
Find a complete list of updates in the Truffle changelog.