diff --git a/common.json b/common.json
index c5da7b2e0734..e20fd6ef0b68 100644
--- a/common.json
+++ b/common.json
@@ -8,7 +8,7 @@
 
   "COMMENT.jdks": "When adding or removing JDKs keep in sync with JDKs in ci/common.jsonnet",
   "jdks": {
-    "galahad-jdk":        {"name": "jpg-jdk",   "version": "25",      "build_id": "jdk-25+6-477", "platformspecific": true, "extrabundles": ["static-libs"]},
+    "galahad-jdk":        {"name": "jpg-jdk",   "version": "25",      "build_id": "jdk-25+6-XXX", "platformspecific": true, "extrabundles": ["static-libs"]},
 
     "oraclejdk17":        {"name": "jpg-jdk",   "version": "17.0.7",  "build_id": "jdk-17.0.7+8", "platformspecific": true, "extrabundles": ["static-libs"]},
     "labsjdk-ce-17":      {"name": "labsjdk",   "version": "ce-17.0.7+4-jvmci-23.1-b02", "platformspecific": true },
diff --git a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/ObjectFile.java b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/ObjectFile.java
index 734c93a025e1..9c679602c4a0 100644
--- a/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/ObjectFile.java
+++ b/substratevm/src/com.oracle.objectfile/src/com/oracle/objectfile/ObjectFile.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -25,6 +25,7 @@
 package com.oracle.objectfile;
 
 import java.io.IOException;
+import java.lang.ref.Cleaner.Cleanable;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.nio.channels.FileChannel;
@@ -1320,9 +1321,19 @@ public final void write(FileChannel outputChannel) {
                 writeBuffer(sortedObjectFileElements, buffer);
             } finally {
                 // unmap immediately
-                ((DirectBuffer) buffer).cleaner().clean();
+                if (Runtime.version().feature() == 21) {
+                    // ((DirectBuffer) buffer).cleaner().clean();
+                    Object cleaner = DirectBuffer.class.getMethod("cleaner").invoke(buffer);
+                    cleaner.getClass().getMethod("clean").invoke(cleaner);
+                } else {
+                    // ((DirectBuffer) buffer).cleanable().clean();
+                    // We use reflection here because DirectBuffer.cleanable does not exist in JDK21.
+                    // This can be replaced when JDK21 support is dropped.
+                    Cleanable cleanable = (Cleanable) DirectBuffer.class.getMethod("cleanable").invoke(buffer);
+                    cleanable.clean();
+                }
             }
-        } catch (IOException e) {
+        } catch (IOException | ReflectiveOperationException e) {
             throw new RuntimeException(e);
         }
     }
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_lang_ref_Cleaner_Cleanable.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_lang_ref_Cleaner_Cleanable.java
new file mode 100644
index 000000000000..3ed4f9c335a5
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_lang_ref_Cleaner_Cleanable.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.svm.core.heap;
+
+import com.oracle.svm.core.NeverInline;
+import com.oracle.svm.core.annotate.AnnotateOriginal;
+import com.oracle.svm.core.annotate.TargetClass;
+
+@TargetClass(className = "java.lang.ref.Cleaner", innerClass="Cleanable")
+public final class Target_java_lang_ref_Cleaner_Cleanable {
+    @AnnotateOriginal
+    @NeverInline("Ensure that every exception can be caught, including implicit exceptions.")
+    native void clean();
+}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_lang_ref_Reference.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_lang_ref_Reference.java
index 29e434368fc1..ad0d036d456d 100644
--- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_lang_ref_Reference.java
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_lang_ref_Reference.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2014, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,7 @@
 import java.lang.reflect.Field;
 import java.util.function.BooleanSupplier;
 
+import com.oracle.svm.core.jdk.JDK21OrEarlier;
 import org.graalvm.nativeimage.Platform;
 import org.graalvm.nativeimage.Platforms;
 import org.graalvm.nativeimage.hosted.FieldValueTransformer;
@@ -156,6 +157,7 @@ boolean refersTo0(Object obj) {
 
     /** May be used by {@code JavaLangRefAccess} via {@code SharedSecrets}. */
     @Substitute
+    @TargetElement(onlyWith = JDK21OrEarlier.class)
     static boolean waitForReferenceProcessing() throws InterruptedException {
         return ReferenceInternals.waitForReferenceProcessing();
     }
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_nio_BufferCleaner.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_nio_BufferCleaner.java
new file mode 100644
index 000000000000..99b977d94bb9
--- /dev/null
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_java_nio_BufferCleaner.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2025, 2025, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.svm.core.heap;
+
+import com.oracle.svm.core.annotate.Alias;
+import com.oracle.svm.core.annotate.RecomputeFieldValue;
+import com.oracle.svm.core.annotate.TargetClass;
+import com.oracle.svm.core.jdk.JDKLatest;
+
+@TargetClass(className = "java.nio.BufferCleaner", onlyWith = JDKLatest.class)
+public final class Target_java_nio_BufferCleaner {
+
+    @Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
+    static Target_java_lang_ref_Cleaner CLEANER;
+}
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_jdk_internal_ref_Cleaner.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_jdk_internal_ref_Cleaner.java
index 682ec5381bff..cf421fd20494 100644
--- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_jdk_internal_ref_Cleaner.java
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/Target_jdk_internal_ref_Cleaner.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012, 2019, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -27,7 +27,6 @@
 import java.lang.ref.Cleaner;
 import java.lang.ref.ReferenceQueue;
 
-import jdk.graal.compiler.serviceprovider.JavaVersionUtil;
 import org.graalvm.nativeimage.hosted.FieldValueTransformer;
 
 import com.oracle.svm.core.NeverInline;
@@ -42,6 +41,7 @@
 import com.oracle.svm.core.thread.VMThreads;
 import com.oracle.svm.util.ReflectionUtil;
 
+import jdk.graal.compiler.serviceprovider.JavaVersionUtil;
 import jdk.internal.misc.InnocuousThread;
 
 @TargetClass(className = "jdk.internal.ref.Cleaner")
@@ -69,13 +69,6 @@ final class Target_java_lang_ref_Cleaner {
     public Target_jdk_internal_ref_CleanerImpl impl;
 }
 
-@TargetClass(className = "java.lang.ref.Cleaner$Cleanable")
-final class Target_java_lang_ref_Cleaner_Cleanable {
-    @AnnotateOriginal
-    @NeverInline("Ensure that every exception can be caught, including implicit exceptions.")
-    native void clean();
-}
-
 @TargetClass(className = "jdk.internal.ref.CleanerImpl")
 final class Target_jdk_internal_ref_CleanerImpl {
 
diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_java_nio_DirectByteBuffer.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_java_nio_DirectByteBuffer.java
index 62efa2660aa9..3b4ecb96211f 100644
--- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_java_nio_DirectByteBuffer.java
+++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_java_nio_DirectByteBuffer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2020, 2025, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -29,6 +29,8 @@
 import com.oracle.svm.core.annotate.Alias;
 import com.oracle.svm.core.annotate.RecomputeFieldValue;
 import com.oracle.svm.core.annotate.TargetClass;
+import com.oracle.svm.core.annotate.TargetElement;
+import com.oracle.svm.core.heap.Target_java_lang_ref_Cleaner_Cleanable;
 import com.oracle.svm.core.heap.Target_jdk_internal_ref_Cleaner;
 import com.oracle.svm.core.util.BasedOnJDKFile;
 import com.oracle.svm.core.util.VMError;
@@ -49,8 +51,13 @@ public final class Target_java_nio_DirectByteBuffer {
      * registered for the buffer by resetting the field {@link #cleaner}.
      */
     @Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
+    @TargetElement(onlyWith = JDK21OrEarlier.class) //
     Target_jdk_internal_ref_Cleaner cleaner;
 
+    @Alias @RecomputeFieldValue(kind = RecomputeFieldValue.Kind.Reset) //
+    @TargetElement(onlyWith = JDKLatest.class) //
+    Target_java_lang_ref_Cleaner_Cleanable cleanable;
+
     @Alias
     @SuppressWarnings("unused")
     Target_java_nio_DirectByteBuffer(long addr, long cap) {