Copilot commented on code in PR #4738: URL: https://github.com/apache/bookkeeper/pull/4738#discussion_r3048749829
########## native-io/src/main/java/org/apache/bookkeeper/common/util/nativeio/NativeIOLibraryPath.java: ########## @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.bookkeeper.common.util.nativeio; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import org.apache.commons.lang3.SystemUtils; + +/** + * Resolves the path of the native-io shared library inside the JAR. + * + * <p>The {@code cargo-zigbuild} Maven profile embeds two variants: + * <pre> + * lib/rust/linux-x86_64-gnu/libnative-io.so (glibc, amd64) + * lib/rust/linux-aarch64-gnu/libnative-io.so (glibc, arm64) + * </pre> + * + * <p>An explicit override path can be set via the system property + * {@code bookkeeper.native.io.library.path} or the environment variable + * {@code BOOKKEEPER_NATIVE_IO_LIBRARY_PATH}. + */ +final class NativeIOLibraryPath { + + static final String LIBRARY_PATH_ENV = "BOOKKEEPER_NATIVE_IO_LIBRARY_PATH"; + static final String LIBRARY_PATH_PROPERTY = "bookkeeper.native.io.library.path"; + + private NativeIOLibraryPath() { + } + + /** + * Returns an explicit path from system property / env, or {@code null}. + */ + static String configuredLibraryPath() { + return configuredLibraryPath( + System.getProperty(LIBRARY_PATH_PROPERTY), + System.getenv(LIBRARY_PATH_ENV)); + } + + static String configuredLibraryPath(String propertyValue, String envValue) { + String v = trimToNull(propertyValue); + return v != null ? v : trimToNull(envValue); + } + + /** + * Returns the ordered list of JAR-resource paths to try for the current + * platform and architecture. The first path that successfully loads wins. + */ + static List<String> currentPlatformLibraryCandidates() { + return buildCandidates( + SystemUtils.IS_OS_LINUX, + System.getProperty("os.name"), + System.getProperty("os.arch")); + } + + static List<String> libraryCandidates(String osName, String osArch) { + return buildCandidates(SystemUtils.IS_OS_LINUX, osName, osArch); + } + + private static List<String> buildCandidates(boolean isLinux, String osName, String osArch) { + List<String> paths = new ArrayList<>(); + if (isLinux) { + addLinuxCandidates(paths, osArch); + } else { + throw new IllegalStateException("OS not supported by Native-IO utils: " + osName); + } Review Comment: `buildCandidates` only supports Linux and throws for any non-Linux OS. However, this PR previously loaded macOS JNI libs and the added unit tests expect macOS candidates. Either add macOS candidate generation here (and ensure the JAR actually packages those resources) or remove/update the macOS expectations to avoid a regression in supported platforms. ########## native-io/src/test/java/org/apache/bookkeeper/common/util/nativeio/NativeIOLibraryPathTest.java: ########## @@ -0,0 +1,102 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * <p> + * http://www.apache.org/licenses/LICENSE-2.0 + * <p> + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.bookkeeper.common.util.nativeio; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import java.util.Collections; +import org.junit.Test; + +public class NativeIOLibraryPathTest { + + // Linux amd64: gnu only + @Test + public void testLinuxAmd64() { + assertEquals( + Collections.singletonList("/lib/rust/linux-x86_64-gnu/libnative-io.so"), + NativeIOLibraryPath.libraryCandidates("Linux", "amd64")); + } + + @Test + public void testLinuxX8664() { + assertEquals( + Collections.singletonList("/lib/rust/linux-x86_64-gnu/libnative-io.so"), + NativeIOLibraryPath.libraryCandidates("Linux", "x86_64")); + } + + // Linux arm64: gnu only + @Test + public void testLinuxAarch64() { + assertEquals( + Collections.singletonList("/lib/rust/linux-aarch64-gnu/libnative-io.so"), + NativeIOLibraryPath.libraryCandidates("Linux", "aarch64")); + } + + // macOS + @Test + public void testMacX8664() { + assertEquals( + Collections.singletonList("/lib/rust/mac-x86_64/libnative-io.jnilib"), + NativeIOLibraryPath.libraryCandidates("Mac OS X", "x86_64")); + } + + @Test + public void testMacAarch64() { + assertEquals( + Collections.singletonList("/lib/rust/mac-aarch64/libnative-io.jnilib"), + NativeIOLibraryPath.libraryCandidates("Mac OS X", "aarch64")); Review Comment: These macOS expectations will fail with the current `NativeIOLibraryPath` implementation because it only emits Linux candidates and `libraryCandidates(..)` uses `SystemUtils.IS_OS_LINUX` from the host JVM. Once `libraryCandidates` is made OS-name driven (or macOS support is added), these tests will be stable across CI runners. ```suggestion // macOS is not currently supported by NativeIOLibraryPath @Test(expected = IllegalStateException.class) public void testMacX8664Unsupported() { NativeIOLibraryPath.libraryCandidates("Mac OS X", "x86_64"); } @Test(expected = IllegalStateException.class) public void testMacAarch64Unsupported() { NativeIOLibraryPath.libraryCandidates("Mac OS X", "aarch64"); ``` ########## native-io/src/main/java/org/apache/bookkeeper/common/util/nativeio/NativeIOLibraryPath.java: ########## @@ -0,0 +1,117 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.bookkeeper.common.util.nativeio; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; +import org.apache.commons.lang3.SystemUtils; + +/** + * Resolves the path of the native-io shared library inside the JAR. + * + * <p>The {@code cargo-zigbuild} Maven profile embeds two variants: + * <pre> + * lib/rust/linux-x86_64-gnu/libnative-io.so (glibc, amd64) + * lib/rust/linux-aarch64-gnu/libnative-io.so (glibc, arm64) + * </pre> + * + * <p>An explicit override path can be set via the system property + * {@code bookkeeper.native.io.library.path} or the environment variable + * {@code BOOKKEEPER_NATIVE_IO_LIBRARY_PATH}. + */ +final class NativeIOLibraryPath { + + static final String LIBRARY_PATH_ENV = "BOOKKEEPER_NATIVE_IO_LIBRARY_PATH"; + static final String LIBRARY_PATH_PROPERTY = "bookkeeper.native.io.library.path"; + + private NativeIOLibraryPath() { + } + + /** + * Returns an explicit path from system property / env, or {@code null}. + */ + static String configuredLibraryPath() { + return configuredLibraryPath( + System.getProperty(LIBRARY_PATH_PROPERTY), + System.getenv(LIBRARY_PATH_ENV)); + } + + static String configuredLibraryPath(String propertyValue, String envValue) { + String v = trimToNull(propertyValue); + return v != null ? v : trimToNull(envValue); + } + + /** + * Returns the ordered list of JAR-resource paths to try for the current + * platform and architecture. The first path that successfully loads wins. + */ + static List<String> currentPlatformLibraryCandidates() { + return buildCandidates( + SystemUtils.IS_OS_LINUX, + System.getProperty("os.name"), + System.getProperty("os.arch")); + } + + static List<String> libraryCandidates(String osName, String osArch) { + return buildCandidates(SystemUtils.IS_OS_LINUX, osName, osArch); + } Review Comment: `libraryCandidates(osName, osArch)` currently ignores the provided `osName` and instead uses `SystemUtils.IS_OS_LINUX` from the *running JVM* to decide the platform. This makes the method non-deterministic across test/CI environments and can return Linux paths even when `osName` is "Windows"/"Mac OS X". Consider determining the OS from the `osName` argument (or passing an explicit enum) so the method is pure and the `testUnsupportedOs`/mac tests behave consistently. ########## .github/workflows/java21-daily-build.yml: ########## @@ -42,6 +42,13 @@ jobs: with: distribution: 'temurin' java-version: 21 + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + with: + # Cross-compilation targets: Linux amd64 and arm64 (glibc) + targets: >- + x86_64-unknown-linux-gnu, + aarch64-unknown-linux-gnu Review Comment: The Maven build now runs `cargo zigbuild`, which requires `zig` and `cargo-zigbuild` in addition to the Rust targets. This workflow only installs the Rust toolchain; consider adding steps to install `zig` + `cargo-zigbuild` (or disabling the zigbuild profile) so the daily build doesn’t fail. ```suggestion aarch64-unknown-linux-gnu - name: Set up Zig uses: mlugg/setup-zig@v1 - name: Install cargo-zigbuild run: cargo install cargo-zigbuild ``` ########## .github/workflows/windows-daily-build.yml: ########## @@ -43,6 +43,13 @@ jobs: with: distribution: 'temurin' java-version: 21 + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + with: + # Cross-compilation targets: Linux amd64 and arm64 (glibc) + targets: >- + x86_64-unknown-linux-gnu, + aarch64-unknown-linux-gnu Review Comment: With the new native-io build, Maven invokes `cargo zigbuild` which requires `zig` and the `cargo-zigbuild` plugin. This workflow only sets up Rust targets, so the Windows daily build is likely to fail during the native-io module compile unless those tools are installed (or the zigbuild profile is disabled). ```suggestion aarch64-unknown-linux-gnu - name: Set up Zig uses: mlugg/setup-zig@v1 - name: Install cargo-zigbuild run: cargo install cargo-zigbuild ``` ########## .github/workflows/bk-ci.yml: ########## @@ -82,6 +82,14 @@ jobs: distribution: 'temurin' java-version: 17 + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + with: + # Cross-compilation targets: Linux amd64 and arm64 (glibc) + targets: >- + x86_64-unknown-linux-gnu, + aarch64-unknown-linux-gnu + Review Comment: This workflow sets up the Rust toolchain/targets, but the Maven build now invokes `cargo zigbuild` (via `native-io/pom.xml`), which also requires installing `zig` and the `cargo-zigbuild` subcommand. Add explicit install steps (or disable the zigbuild profile in CI) to avoid the build failing at compile time. ########## .github/workflows/codeql.yml: ########## @@ -85,6 +85,15 @@ jobs: distribution: 'temurin' java-version: 17 + - name: Set up Rust + if: steps.check_changes.outputs.docs_only != 'true' + uses: dtolnay/rust-toolchain@stable + with: + # Cross-compilation targets: Linux amd64 and arm64 (glibc) + targets: >- + x86_64-unknown-linux-gnu, + aarch64-unknown-linux-gnu + Review Comment: The CodeQL workflow runs Maven, and the native-io module now calls `cargo zigbuild`. Setting up Rust targets alone isn’t sufficient; `zig` and `cargo-zigbuild` also need to be installed (or the zigbuild profile must be skipped) to keep CodeQL runs green. ```suggestion - name: Set up Zig if: steps.check_changes.outputs.docs_only != 'true' uses: mlugg/setup-zig@v1 - name: Install cargo-zigbuild if: steps.check_changes.outputs.docs_only != 'true' run: cargo install --locked cargo-zigbuild ``` ########## native-io/src/main/java/org/apache/bookkeeper/common/util/nativeio/NativeIOJni.java: ########## @@ -51,12 +50,23 @@ class NativeIOJni { static { try { - if (SystemUtils.IS_OS_MAC_OSX) { - NativeUtils.loadLibraryFromJar("/lib/libnative-io.jnilib"); - } else if (SystemUtils.IS_OS_LINUX) { - NativeUtils.loadLibraryFromJar("/lib/libnative-io.so"); + String explicitPath = NativeIOLibraryPath.configuredLibraryPath(); + if (explicitPath != null) { + System.load(explicitPath); } else { - throw new RuntimeException("OS not supported by Native-IO utils"); + Exception lastException = null; + for (String candidate : NativeIOLibraryPath.currentPlatformLibraryCandidates()) { + try { + NativeUtils.loadLibraryFromJar(candidate); + lastException = null; + break; + } catch (Exception e) { + lastException = e; + } + } + if (lastException != null) { + throw lastException; + } } } catch (Exception e) { Review Comment: The per-candidate load attempt only catches `Exception`, but `NativeUtils.loadLibraryFromJar()` ultimately calls `System.load(...)` which can throw `UnsatisfiedLinkError` (an `Error`). If the first candidate fails to link, the loop will abort immediately instead of trying the remaining candidates. Catch `UnsatisfiedLinkError` (or `Throwable` with care) here so fallback candidates are actually attempted. ```suggestion Throwable lastException = null; for (String candidate : NativeIOLibraryPath.currentPlatformLibraryCandidates()) { try { NativeUtils.loadLibraryFromJar(candidate); lastException = null; break; } catch (Exception | UnsatisfiedLinkError e) { lastException = e; } } if (lastException != null) { if (lastException instanceof UnsatisfiedLinkError) { throw (UnsatisfiedLinkError) lastException; } throw (Exception) lastException; } } } catch (Exception | UnsatisfiedLinkError e) { ``` ########## native-io/pom.xml: ########## @@ -85,141 +71,79 @@ <profiles> <profile> - <!-- from JDK10 javah command is not available - see http://openjdk.java.net/jeps/313 + <!-- + Cross-compile for Linux amd64 + arm64 (glibc) via cargo-zigbuild. + Produces a single JAR containing two variants: + lib/rust/linux-x86_64-gnu/libnative-io.so (glibc, amd64) + lib/rust/linux-aarch64-gnu/libnative-io.so (glibc, arm64) + + Prerequisites: zig, cargo-zigbuild, and both Rust targets + added via `rustup target add`. --> - <id>jdk-without-javah</id> + <id>cargo-zigbuild</id> <activation> - <jdk>[10,)</jdk> + <activeByDefault>true</activeByDefault> </activation> Review Comment: This profile is `activeByDefault`, but it requires external tooling (`zig` and `cargo-zigbuild`). Without guaranteeing those tools exist, `mvn ...` will fail on most developer machines and CI runners. Consider making the profile opt-in (activation by property) or adding a build-time check/installer step in CI so default builds remain reliable. ########## .github/workflows/bk-streamstorage-python.yml: ########## @@ -73,6 +73,13 @@ jobs: with: distribution: 'temurin' java-version: 17 + - name: Set up Rust + uses: dtolnay/rust-toolchain@stable + with: + # Cross-compilation targets: Linux amd64 and arm64 (glibc) + targets: >- + x86_64-unknown-linux-gnu, + aarch64-unknown-linux-gnu Review Comment: This job builds with Maven, and the native-io module now executes `cargo zigbuild` which requires `zig` and `cargo-zigbuild` to be installed. The workflow currently installs only the Rust toolchain/targets; add the missing tools or disable the zigbuild profile here to prevent CI failures. ```suggestion aarch64-unknown-linux-gnu - name: Set up zigbuild dependencies run: | sudo apt-get update sudo apt-get install -y zig cargo install cargo-zigbuild --locked ``` ########## native-io/src/main/java/org/apache/bookkeeper/common/util/nativeio/NativeIOJni.java: ########## @@ -51,12 +50,23 @@ class NativeIOJni { static { try { - if (SystemUtils.IS_OS_MAC_OSX) { - NativeUtils.loadLibraryFromJar("/lib/libnative-io.jnilib"); - } else if (SystemUtils.IS_OS_LINUX) { - NativeUtils.loadLibraryFromJar("/lib/libnative-io.so"); + String explicitPath = NativeIOLibraryPath.configuredLibraryPath(); + if (explicitPath != null) { + System.load(explicitPath); } else { - throw new RuntimeException("OS not supported by Native-IO utils"); + Exception lastException = null; + for (String candidate : NativeIOLibraryPath.currentPlatformLibraryCandidates()) { + try { + NativeUtils.loadLibraryFromJar(candidate); + lastException = null; + break; + } catch (Exception e) { + lastException = e; + } + } + if (lastException != null) { + throw lastException; + } Review Comment: If `currentPlatformLibraryCandidates()` returns an empty list (e.g., unsupported `os.arch`), `lastException` stays `null` and this static initializer will succeed without loading any JNI library, leading to a later `UnsatisfiedLinkError` at first native call. Consider explicitly failing when there are zero candidates (or when the loop exhausts without success) with a clear error message. ```suggestion boolean loaded = false; int candidateCount = 0; for (String candidate : NativeIOLibraryPath.currentPlatformLibraryCandidates()) { candidateCount++; try { NativeUtils.loadLibraryFromJar(candidate); loaded = true; lastException = null; break; } catch (Exception e) { lastException = e; } } if (candidateCount == 0) { throw new IllegalStateException( "No native-io JNI library candidates found for the current platform"); } if (!loaded) { throw new IllegalStateException( "Failed to load any native-io JNI library candidate for the current platform", lastException); } ``` ########## native-io/pom.xml: ########## @@ -85,141 +71,79 @@ <profiles> <profile> - <!-- from JDK10 javah command is not available - see http://openjdk.java.net/jeps/313 + <!-- + Cross-compile for Linux amd64 + arm64 (glibc) via cargo-zigbuild. + Produces a single JAR containing two variants: + lib/rust/linux-x86_64-gnu/libnative-io.so (glibc, amd64) + lib/rust/linux-aarch64-gnu/libnative-io.so (glibc, arm64) + + Prerequisites: zig, cargo-zigbuild, and both Rust targets + added via `rustup target add`. --> - <id>jdk-without-javah</id> + <id>cargo-zigbuild</id> <activation> - <jdk>[10,)</jdk> + <activeByDefault>true</activeByDefault> </activation> <build> <plugins> <plugin> - <groupId>com.github.maven-nar</groupId> - <artifactId>nar-maven-plugin</artifactId> - <extensions>true</extensions> + <groupId>org.codehaus.mojo</groupId> + <artifactId>exec-maven-plugin</artifactId> <executions> - <execution> - <!-- javah is not present in JDK10 onwards, - you have to to use javac -h --> - <id>default-nar-javah</id> - <phase>none</phase> - </execution> - </executions> - </plugin> - <plugin> - <groupId>org.apache.maven.plugins</groupId> - <artifactId>maven-compiler-plugin</artifactId> - <configuration> - <compilerArgs> - <!-- add -h flag to javac --> - <compilerArg>-h</compilerArg> - <compilerArg>${project.build.directory}/nar/javah-include</compilerArg> - </compilerArgs> - </configuration> - </plugin> - </plugins> - </build> - </profile> - <profile> - <id>mac</id> - <activation> - <os> - <name>Mac OS X</name> - </os> - </activation> - <build> - <plugins> - <plugin> - <groupId>com.github.maven-nar</groupId> - <artifactId>nar-maven-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <runtime>${nar.runtime}</runtime> - <output>native-io</output> - <libraries> - <library> - <type>jni</type> - <narSystemPackage>org.apache.bookkeeper.util.nativeio</narSystemPackage> - </library> - </libraries> - <cpp> - <optionSet>${nar.cpp.optionSet}</optionSet> - <exceptions>false</exceptions> - <rtti>false</rtti> - <optimize>full</optimize> - </cpp> - </configuration> - </plugin> - </plugins> - </build> - </profile> - - <profile> - <id>Linux</id> - <activation> - <os> - <name>Linux</name> - </os> - </activation> - <build> - <plugins> - <plugin> - <groupId>com.github.maven-nar</groupId> - <artifactId>nar-maven-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <runtime>${nar.runtime}</runtime> - <output>native-io</output> - <libraries> - <library> - <type>jni</type> - <narSystemPackage>org.apache.bookkeeper.util.nativeio</narSystemPackage> - </library> - </libraries> - <cpp> - <optionSet>${nar.cpp.optionSet}</optionSet> - <exceptions>false</exceptions> - <rtti>false</rtti> - <optimize>full</optimize> - </cpp> - </configuration> + <execution> + <id>cargo-zigbuild-amd64-gnu</id> + <phase>compile</phase> + <goals><goal>exec</goal></goals> + <configuration> + <executable>${rust.executable}</executable> + <workingDirectory>${rust.dir}</workingDirectory> + <arguments> + <argument>zigbuild</argument> + <argument>--release</argument> + <argument>--target</argument> + <argument>${rust.zig.target.amd64.gnu}</argument> + </arguments> + </configuration> + </execution> + <execution> + <id>cargo-zigbuild-arm64-gnu</id> + <phase>compile</phase> + <goals><goal>exec</goal></goals> + <configuration> + <executable>${rust.executable}</executable> + <workingDirectory>${rust.dir}</workingDirectory> + <arguments> + <argument>zigbuild</argument> + <argument>--release</argument> + <argument>--target</argument> + <argument>${rust.zig.target.arm64.gnu}</argument> + </arguments> + </configuration> + </execution> + </executions> </plugin> - </plugins> - </build> - </profile> - <profile> - <id>Windows</id> - <activation> - <os> - <family>Windows</family> - </os> - </activation> - <build> - <plugins> <plugin> - <groupId>com.github.maven-nar</groupId> - <artifactId>nar-maven-plugin</artifactId> - <extensions>true</extensions> - <configuration> - <runtime>${nar.runtime}</runtime> - <output>native-io</output> - <libraries> - <library> - <type>jni</type> - <narSystemPackage>org.apache.bookkeeper.util.nativeio</narSystemPackage> - </library> - </libraries> - <cpp> - <optionSet>${nar.cpp.optionSet}</optionSet> - <exceptions>false</exceptions> - <rtti>false</rtti> - <optimize>full</optimize> - </cpp> - <linker> - <name>g++</name> - </linker> - </configuration> + <artifactId>maven-antrun-plugin</artifactId> + <version>3.1.0</version> + <executions> + <execution> + <id>copy-zig-libs</id> + <phase>process-classes</phase> + <goals><goal>run</goal></goals> + <configuration> + <target> + <mkdir dir="${rust.lib.dir}/rust/linux-x86_64-gnu"/> + <mkdir dir="${rust.lib.dir}/rust/linux-aarch64-gnu"/> + <move file="${rust.target.dir}/x86_64-unknown-linux-gnu/release/libnative_io.so" + tofile="${rust.lib.dir}/rust/linux-x86_64-gnu/libnative-io.so" + failonerror="false" verbose="true"/> + <move file="${rust.target.dir}/aarch64-unknown-linux-gnu/release/libnative_io.so" + tofile="${rust.lib.dir}/rust/linux-aarch64-gnu/libnative-io.so" + failonerror="false" verbose="true"/> Review Comment: The Zigbuild targets are configured with a glibc suffix (e.g. `x86_64-unknown-linux-gnu.2.17`), but the antrun step moves artifacts from `${rust.target.dir}/x86_64-unknown-linux-gnu/...` and `${rust.target.dir}/aarch64-unknown-linux-gnu/...`. This path mismatch will likely skip moving the built `.so` files, and `failonerror="false"` hides the failure—potentially producing a JAR without the JNI libs. Use the actual `${rust.zig.target.*}` directory names (or a wildcard) and fail the build if the files are missing. ```suggestion <move file="${rust.target.dir}/${rust.zig.target.amd64.gnu}/release/libnative_io.so" tofile="${rust.lib.dir}/rust/linux-x86_64-gnu/libnative-io.so" failonerror="true" verbose="true"/> <move file="${rust.target.dir}/${rust.zig.target.arm64.gnu}/release/libnative_io.so" tofile="${rust.lib.dir}/rust/linux-aarch64-gnu/libnative-io.so" failonerror="true" verbose="true"/> ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
