From 48a8af38882a95c0663ca0cede59f5ff4c604cd5 Mon Sep 17 00:00:00 2001 From: Xuanwo Date: Mon, 22 Dec 2025 21:05:50 +0800 Subject: [PATCH 01/11] feat(bindings/java): Add musl platform support --- .github/workflows/release_java.yml | 16 ++++ .../java/org/apache/opendal/Environment.java | 55 ++++++++++- .../org/apache/opendal/NativeLibrary.java | 96 ++++++++++++++++--- .../org/apache/opendal/EnvironmentTest.java | 67 +++++++++++++ bindings/java/tools/build.py | 11 ++- 5 files changed, 228 insertions(+), 17 deletions(-) create mode 100644 bindings/java/src/test/java/org/apache/opendal/EnvironmentTest.java diff --git a/.github/workflows/release_java.yml b/.github/workflows/release_java.yml index c530d0fcb5bb..fea5d57226a5 100644 --- a/.github/workflows/release_java.yml +++ b/.github/workflows/release_java.yml @@ -42,8 +42,12 @@ jobs: include: - os: ubuntu-latest classifier: linux-x86_64 + - os: ubuntu-latest + classifier: linux-x86_64-musl - os: ubuntu-24.04-arm classifier: linux-aarch_64 + - os: ubuntu-24.04-arm + classifier: linux-aarch_64-musl - os: windows-latest classifier: windows-x86_64 - os: macos-latest @@ -135,11 +139,21 @@ jobs: with: name: linux-x86_64-local-staging path: ~/linux-x86_64-local-staging + - name: Download linux x86_64 (musl) staging directory + uses: actions/download-artifact@v5 + with: + name: linux-x86_64-musl-local-staging + path: ~/linux-x86_64-musl-local-staging - name: Download linux aarch_64 staging directory uses: actions/download-artifact@v5 with: name: linux-aarch_64-local-staging path: ~/linux-aarch_64-local-staging + - name: Download linux aarch_64 (musl) staging directory + uses: actions/download-artifact@v5 + with: + name: linux-aarch_64-musl-local-staging + path: ~/linux-aarch_64-musl-local-staging - name: Download darwin staging directory uses: actions/download-artifact@v5 with: @@ -160,7 +174,9 @@ jobs: python ./scripts/merge_local_staging.py $LOCAL_STAGING_DIR/staging \ ~/windows-x86_64-local-staging/staging \ ~/linux-x86_64-local-staging/staging \ + ~/linux-x86_64-musl-local-staging/staging \ ~/linux-aarch_64-local-staging/staging \ + ~/linux-aarch_64-musl-local-staging/staging \ ~/osx-x86_64-local-staging/staging \ ~/osx-aarch_64-local-staging/staging diff --git a/bindings/java/src/main/java/org/apache/opendal/Environment.java b/bindings/java/src/main/java/org/apache/opendal/Environment.java index ccdaab8caab7..5f6edc65d49e 100644 --- a/bindings/java/src/main/java/org/apache/opendal/Environment.java +++ b/bindings/java/src/main/java/org/apache/opendal/Environment.java @@ -22,6 +22,8 @@ import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; +import java.nio.file.Files; +import java.nio.file.Paths; import java.util.Properties; /** @@ -31,6 +33,7 @@ public enum Environment { INSTANCE; public static final String UNKNOWN = ""; + private static final String LIBC_PROPERTY = "org.apache.opendal.libc"; private String classifier = UNKNOWN; private String projectVersion = UNKNOWN; @@ -44,8 +47,18 @@ public enum Environment { throw new UncheckedIOException("cannot load environment properties file", e); } + INSTANCE.classifier = detectClassifier(System.getProperty("os.name"), System.getProperty("os.arch")); + } + + static String detectClassifier(String osName, String osArch) { + final String os = osName == null ? "" : osName.toLowerCase(); + final String arch = osArch == null ? "" : osArch.toLowerCase(); + final boolean musl = !os.startsWith("windows") && !os.startsWith("mac") && isMusl(arch); + return buildClassifier(os, arch, musl); + } + + static String buildClassifier(String os, String arch, boolean musl) { final StringBuilder classifier = new StringBuilder(); - final String os = System.getProperty("os.name").toLowerCase(); if (os.startsWith("windows")) { classifier.append("windows"); } else if (os.startsWith("mac")) { @@ -54,13 +67,49 @@ public enum Environment { classifier.append("linux"); } classifier.append("-"); - final String arch = System.getProperty("os.arch").toLowerCase(); if (arch.equals("aarch64")) { classifier.append("aarch_64"); } else { classifier.append("x86_64"); } - INSTANCE.classifier = classifier.toString(); + if (classifier.toString().startsWith("linux-") && musl) { + classifier.append("-musl"); + } + return classifier.toString(); + } + + static boolean isMusl(String osArch) { + final String override = System.getProperty(LIBC_PROPERTY); + if (override != null) { + final String libc = override.trim().toLowerCase(); + if (libc.equals("musl")) { + return true; + } + if (libc.equals("gnu") || libc.equals("glibc")) { + return false; + } + } + + final String loader = muslLoaderName(osArch); + if (loader == null) { + return false; + } + return Files.exists(Paths.get("/lib", loader)) || Files.exists(Paths.get("/usr/lib", loader)); + } + + private static String muslLoaderName(String osArch) { + if (osArch == null) { + return null; + } + switch (osArch) { + case "aarch64": + return "ld-musl-aarch64.so.1"; + case "x86_64": + case "amd64": + return "ld-musl-x86_64.so.1"; + default: + return null; + } } /** diff --git a/bindings/java/src/main/java/org/apache/opendal/NativeLibrary.java b/bindings/java/src/main/java/org/apache/opendal/NativeLibrary.java index bc67e3237610..4e65c59d010a 100644 --- a/bindings/java/src/main/java/org/apache/opendal/NativeLibrary.java +++ b/bindings/java/src/main/java/org/apache/opendal/NativeLibrary.java @@ -59,6 +59,8 @@ private enum LibraryState { *