Skip to content

Java: add Windows ARM64 (win-arm64) target to rocksdbjni#14699

Open
dunwan wants to merge 1 commit into
facebook:mainfrom
dunwan:windows-arm64-jni
Open

Java: add Windows ARM64 (win-arm64) target to rocksdbjni#14699
dunwan wants to merge 1 commit into
facebook:mainfrom
dunwan:windows-arm64-jni

Conversation

@dunwan
Copy link
Copy Markdown

@dunwan dunwan commented May 2, 2026

PR draft — rocksdbjni (facebook/rocksdb): Windows ARM64 support

Upstream status (checked 2026-04-24): facebook/rocksdb is actively
maintained. No open or closed PR exists for the search
is:pr win-arm64 java. A Meta Open-Source CLA signature is required
(one-time, individual or corporate) at https://code.facebook.com/cla
before the PR can be merged.

Recommended phasing:

  • PR A (this draft) — Java + CMake changes. Small, safe, reviewable.
  • PR B (follow-up) — CI/release-pipeline change to publish
    rocksdbjni-<ver>-win-arm64.jar to Maven Central. Larger scope;
    best sequenced after PR A lands.

Title

Java: add Windows ARM64 (win-arm64) target to rocksdbjni

Summary

Adds support for loading and building rocksdbjni on Windows ARM64.

  • Environment.isAarch64() now also matches os.arch=arm64 (which is
    what Windows ARM64 JVMs report; Linux/macOS ARM JVMs already report
    aarch64).
  • Environment.getJniLibraryFileName() returns
    librocksdbjni-win-arm64.dll on 64-bit Windows ARM64, matching the
    existing -win64 / -linux64 naming scheme.
  • java/CMakeLists.txt emits the matching OUTPUT_NAME and ROCKSDB_JAR
    names under if(CMAKE_SYSTEM_PROCESSOR MATCHES arm64|aarch64|ARM64|AARCH64)
    on Windows.
  • New EnvironmentTest.winArm64() unit test pins the expected behaviour.

Every hunk is strictly additive on every non-ARM64 platform — existing
Windows x64, Linux, macOS, Solaris, AIX, FreeBSD builds produce byte-for-byte
identical artifact names.

The native ARM64 DLL itself is not committed (matches current practice for
-linux64 / -win64); building it is gated by the java/CMakeLists.txt
change. The release-pipeline change to publish rocksdbjni-<ver>-win-arm64.jar
to Maven Central is intentionally deferred to a follow-up PR.

Motivation

Windows on ARM64 is now a first-class target for Java workloads — Azul,
Adoptium, Microsoft and Corretto all ship ARM64 JDKs. Apache Kafka and
other projects that depend on org.rocksdb:rocksdbjni currently fail at
startup on Windows ARM64 because:

  1. Environment.isAarch64() returns false for os.arch=arm64 (the
    string Windows ARM64 JVMs actually report).
  2. Even if it returned true, getJniLibraryFileName() would fall
    through to librocksdbjni-win64.dll — which either doesn't exist in
    the ARM64 JAR or is an x64 binary that fails to load.

Changes

1. java/src/main/java/org/rocksdb/util/Environment.java

--- a/java/src/main/java/org/rocksdb/util/Environment.java
+++ b/java/src/main/java/org/rocksdb/util/Environment.java
@@ -25,7 +25,7 @@ public class Environment {
   private static Boolean MUSL_LIBC = null;

   public static boolean isAarch64() {
-    return ARCH.contains("aarch64");
+    return ARCH.contains("aarch64") || ARCH.contains("arm64");
   }

@@ -211,6 +211,9 @@ public class Environment {
       final String arch = is64Bit() ? "64" : "32";
       return String.format("%sjni-solaris%s", name, arch);
     } else if (isWindows() && is64Bit()) {
+      if (isAarch64()) {
+        return String.format("%sjni-win-arm64", name);
+      }
       return String.format("%sjni-win64", name);

2. java/src/test/java/org/rocksdb/util/EnvironmentTest.java

+  @Test
+  public void winArm64() {
+    setEnvironmentClassFields("win", "arm64");
+    assertThat(Environment.isWindows()).isTrue();
+    assertThat(Environment.isAarch64()).isTrue();
+    assertThat(Environment.getJniLibraryExtension()).
+      isEqualTo(".dll");
+    assertThat(Environment.getJniLibraryFileName("rocksdb")).
+      isEqualTo("librocksdbjni-win-arm64.dll");
+    assertThat(Environment.getFallbackJniLibraryFileName("rocksdb")).isNull();
+    assertThat(Environment.getSharedLibraryFileName("rocksdb")).
+      isEqualTo("librocksdbjni.dll");
+  }

3. java/CMakeLists.txt

--- a/java/CMakeLists.txt
+++ b/java/CMakeLists.txt
@@ -845,12 +845,21 @@ if(CMAKE_SIZEOF_VOID_P EQUAL 8)
 endif()

 if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
+  if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64|ARM64|AARCH64")
     set_target_properties(
-            ${ROCKSDBJNI_STATIC_LIB}
-            PROPERTIES
-            OUTPUT_NAME librocksdbjni-win${bitness}
+        ${ROCKSDBJNI_STATIC_LIB}
+        PROPERTIES
+        OUTPUT_NAME librocksdbjni-win-arm64
+    )
+    set(ROCKSDB_JAR rocksdbjni-${CMAKE_PROJECT_VERSION}-win-arm64.jar)
+  else()
+    set_target_properties(
+        ${ROCKSDBJNI_STATIC_LIB}
+        PROPERTIES
+        OUTPUT_NAME librocksdbjni-win${bitness}
     )
     set(ROCKSDB_JAR rocksdbjni-${CMAKE_PROJECT_VERSION}-win${bitness}.jar)
+  endif()
 elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")

Safety analysis — why non-ARM64 builds are unaffected

  1. isAarch64() — adding || ARCH.contains("arm64") is a strict
    disjunctive widening; it cannot flip any existing truefalse.
    The only other way it could change behaviour is if another recognised
    arch string happened to contain the substring "arm64". None of the
    strings RocksDB checks for do: amd64, x86_64, x86, i386,
    ppc, ppc64, ppc64le, s390x, riscv64, aarch64, sparc.
  2. getJniLibraryFileName() — the new branch is nested inside the
    existing isWindows() && is64Bit() clause. It is unreachable on
    Linux, macOS, Solaris, AIX, FreeBSD and 32-bit Windows. On 64-bit
    Windows it only fires for ARM64 JVMs — which previously produced the
    wrong librocksdbjni-win64.dll name and failed to load, so no
    production behaviour is being changed.
  3. java/CMakeLists.txt — guarded by
    CMAKE_SYSTEM_PROCESSOR MATCHES arm64|aarch64|ARM64|AARCH64. On
    x64 Windows CMAKE_SYSTEM_PROCESSOR is AMD64, so the else branch
    is taken and the original OUTPUT_NAME librocksdbjni-win${bitness} /
    ROCKSDB_JAR rocksdbjni-<ver>-win${bitness}.jar targets are emitted
    unchanged. The Linux/macOS/Unix branches
    (elseif(... Linux), etc.) are not touched.

Build evidence (reproducible)

Host: Surface Laptop 7 (Snapdragon X1E80100), Windows 11 ARM64,
VS 2026 MSVC 14.50.35717 ARM64 cross toolchain, JDK 17 Adoptium.

# (ARM64 cross-env loaded via vcvarsall amd64_arm64; see full script
# in windows-arm64-progress.md)

cmake -S . -B java\build-arm64 -G "Ninja" `
      -DJNI=1 -DPORTABLE=1 -DWITH_GFLAGS=0 `
      -DWITH_TESTS=OFF -DWITH_BENCHMARK_TOOLS=OFF -DWITH_TOOLS=OFF `
      -DWITH_CORE_TOOLS=OFF -DWITH_ALL_TESTS=OFF `
      -DROCKSDB_BUILD_SHARED=OFF -DCMAKE_BUILD_TYPE=Release

cmake --build java\build-arm64 --target rocksdbjni   --config Release
cmake --build java\build-arm64 --target rocksdbjava  --config Release

Artifacts produced:

File Size PE machine Notes
librocksdbjni-win-arm64.dll 13,586,944 B AA64 (ARM64) 1,541 Java_org_rocksdb_* JNI exports
rocksdbjni-<ver>-win-arm64.jar 4,625,859 B Contains the DLL at JAR root alongside HISTORY-JAVA.md

dumpbin /DEPENDENTS on the DLL reports only stock Windows dependencies:
SHLWAPI.dll, RPCRT4.dll, KERNEL32.dll, MSVCP140.dll,
VCRUNTIME140.dll, api-ms-win-crt-*.dll.

Note about -DWITH_TESTS=OFF

java/CMakeLists.txt unconditionally downloads junit / hamcrest / mockito /
cglib / assertj-core from rocksdb-deps.s3-us-west-2.amazonaws.com at
configure time, even with -DWITH_TESTS=OFF. The
assertj-core-2.9.0.jar S3 URL hangs intermittently during download;
pre-seeding java/test-libs/assertj-core-2.9.0.jar from Maven Central
works around this. Happy to fold a separate, small fix for this into
this PR or a follow-up if the reviewers prefer.

Test results

  • EnvironmentTest (all cases including new winArm64) — pass.
  • Native round-trip smoke test on Windows 11 ARM64: open DB, put
    1,000 keys, flush, compact, get back — pass.

Checklist

  • CLA signed (https://code.facebook.com/cla) — sign before
    opening the PR.
  • Rebased onto facebook/rocksdb:main.
  • Behaviour unchanged on every non-Windows-ARM64 platform (see
    safety analysis).
  • EnvironmentTest.winArm64 added.
  • Verified on real Windows 11 ARM64 hardware.
  • Follow-up CI/release-pipeline PR to publish
    rocksdbjni-<ver>-win-arm64.jar to Maven Central.

Draft authored 2026-04-24. See windows-arm64-progress.md in the Kafka
ARM64 validation tree for the full session notes and build logs.

On Windows ARM64 the JVM reports os.arch=arm64 (vs aarch64 on
Linux/macOS). This patch:

* Environment.isAarch64() also matches 'arm64'.
* getJniLibraryFileName() emits 'librocksdbjni-win-arm64.dll' on
  64-bit Windows when isAarch64() is true.
* java/CMakeLists.txt emits matching OUTPUT_NAME / ROCKSDB_JAR
  names under CMAKE_SYSTEM_PROCESSOR MATCHES arm64|aarch64.
* New EnvironmentTest.winArm64 unit test.

All hunks are guarded so non-ARM64 Windows, Linux, macOS, Solaris,
AIX, FreeBSD and 32-bit builds emit byte-for-byte identical artifact
names. Verified on Windows 11 ARM64 / VS 2026 MSVC arm64 / JDK 17.

Signed-off-by: dunwan <[email protected]>
@meta-cla meta-cla Bot added the CLA Signed label May 2, 2026
@dunwan dunwan marked this pull request as ready for review May 2, 2026 15:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant