Skip to content

Test Java API on Windows arm64 - #3801

Merged
csukuangfj merged 6 commits into
k2-fsa:masterfrom
csukuangfj:win-arm64
Jul 24, 2026
Merged

csukuangfj merged 6 commits into
k2-fsa:masterfrom
csukuangfj:win-arm64

Conversation

@csukuangfj

@csukuangfj csukuangfj commented Jul 24, 2026 •

Copy link
Copy Markdown
Collaborator

Summary by CodeRabbit

  • New Features

    • Added Windows ARM64 support for Java/JNI builds, packaged native libraries, Gradle, Maven, and automated testing.
    • Improved native library discovery so Java examples load bundled runtime components more reliably across supported platforms.
  • Bug Fixes

    • Corrected platform and architecture detection for Windows ARM64.
    • Updated Java examples to locate native libraries consistently.
  • Documentation

    • Added Windows ARM64 to supported-platform listings and setup guidance.
  • Chores

    • Updated release automation and artifact publishing for the latest native packages.

@dosubot dosubot Bot added the size:M This PR changes 30-99 lines, ignoring generated files. label Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Windows ARM64 support is added across JNI builds, native JAR packaging, Java example launchers, Gradle/Maven metadata, CI matrices, native tests, and release publication. Java native loading now resolves ONNX Runtime from the configured native directory and maps Windows ARM64 resources separately.

Windows ARM64 Java and JNI support

Layer / File(s) Summary
Java native loading and example integration
sherpa-onnx/java-api/..., java-api-examples/*, jitpack.yml
Java launchers use sherpa_onnx.native.path; LibraryUtils loads ONNX Runtime from that directory and maps Windows ARM64 as win-arm64. Example metadata and dependencies document the new native artifact.
Windows ARM64 JNI packaging and publication
.github/workflows/windows-arm64-jni.yaml
Builds, installs, archives, uploads, and publishes Windows ARM64 JNI artifacts.
Windows ARM64 native build and tests
.github/workflows/windows-arm64.yaml
Uses the Windows ARM runner and adds conditional native tests across speech, TTS, C API, and identification scenarios.
Java CI matrices and native JAR packaging
.github/workflows/jar.yaml, .github/workflows/run-java-test.yaml
Adds Windows ARM64 matrices, downloads ARM64 JNI libraries, generates the win-arm64 native JAR, updates classpaths, and adjusts CMake installation and caching.
Release routing updates
.github/workflows/linux-jni*.yaml, .github/workflows/windows-x64-jni.yaml
Updates release tags and separates Windows x64 release upload paths.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant JavaExample
  participant LibraryUtils
  participant NativeDirectory
  JavaExample->>LibraryUtils: provide sherpa_onnx.native.path
  LibraryUtils->>NativeDirectory: load onnxruntime
  LibraryUtils->>NativeDirectory: load sherpa-onnx-jni
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main change: adding Windows ARM64 coverage for the Java API and related workflows.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@csukuangfj
csukuangfj merged commit 546df6f into k2-fsa:master Jul 24, 2026
1 check was pending
@csukuangfj
csukuangfj deleted the win-arm64 branch July 24, 2026 11:11

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 11

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/linux-jni-aarch64.yaml:
- Line 184: Replace the hard-coded v1.13.4 release tag with the pushed tag
expression github.ref_name in the fork release paths at
.github/workflows/linux-jni-aarch64.yaml:184,
.github/workflows/linux-jni.yaml:203, and
.github/workflows/windows-x64-jni.yaml:105, preserving the existing release
upload behavior.

In @.github/workflows/windows-arm64-jni.yaml:
- Around line 26-28: Update the actions/checkout@v4 step to disable credential
persistence by setting persist-credentials to false in its with configuration,
while preserving fetch-depth: 0 and the existing workflow steps.
- Around line 76-94: Remove the silent-failure fallback from the library copy
command in the “Copy files” step. Make the copy of build/install/lib into $dst
fail the workflow when the source is missing or the copy is unsuccessful, while
preserving the existing archive creation and release-upload flow for successful
copies.

In `@java-api-examples/run-audio-tagging-ced-from-file.sh`:
- Line 14: Quote the $PWD-based native-path JVM argument in every affected
launcher so paths containing spaces remain a single argument:
java-api-examples/run-audio-tagging-ced-from-file.sh:14,
run-non-streaming-decode-file-fire-red-asr-ctc.sh:15,
run-non-streaming-decode-file-fire-red-asr.sh:15,
run-non-streaming-decode-file-funasr-nano.sh:14,
run-non-streaming-decode-file-medasr-ctc.sh:15,
run-non-streaming-decode-file-moonshine-v2.sh:14,
run-non-streaming-decode-file-moonshine.sh:14,
run-non-streaming-decode-file-nemo-canary.sh:14,
run-non-streaming-decode-file-nemo.sh:14,
run-non-streaming-decode-file-omnilingual-asr-ctc.sh:15, and
run-non-streaming-decode-file-paraformer.sh:15. Apply the same quoting to each
native-path value without changing the surrounding launcher behavior.

In `@java-api-examples/run-audio-tagging-zipformer-from-file.sh`:
- Line 14: Quote the $PWD-based native library path in the launcher arguments so
checkout paths containing spaces remain a single Java option. Apply this change
to java-api-examples/run-audio-tagging-zipformer-from-file.sh:14,
java-api-examples/run-non-streaming-decode-file-qwen3-asr.sh:14,
java-api-examples/run-non-streaming-decode-file-sense-voice-with-hr.sh:24,
java-api-examples/run-non-streaming-decode-file-sense-voice.sh:14,
java-api-examples/run-non-streaming-decode-file-tele-speech-ctc.sh:14,
java-api-examples/run-non-streaming-decode-file-transducer-hotwords.sh:20,
java-api-examples/run-non-streaming-decode-file-transducer.sh:15,
java-api-examples/run-non-streaming-decode-file-wenet-ctc.sh:14,
java-api-examples/run-non-streaming-decode-file-whisper-multiple.sh:15,
java-api-examples/run-non-streaming-decode-file-whisper.sh:15,
java-api-examples/run-non-streaming-decode-file-zipformer-ctc.sh:15, and
java-api-examples/run-non-streaming-speech-enhancement-dpdfnet.sh:16.

In `@java-api-examples/run-inverse-text-normalization-paraformer.sh`:
- Line 23: Quote the -Dsherpa_onnx.native.path JVM argument wherever it appears
to prevent shell splitting and glob expansion: update
java-api-examples/run-inverse-text-normalization-paraformer.sh:23,
run-non-streaming-speech-enhancement-gtcrn.sh:16,
run-non-streaming-tts-coqui-de.sh:17, run-non-streaming-tts-kitten-en.sh:18,
run-non-streaming-tts-kokoro-en.sh:17, run-non-streaming-tts-kokoro-zh-en.sh:17,
run-non-streaming-tts-matcha-en.sh:22, run-non-streaming-tts-matcha-zh.sh:21,
run-non-streaming-tts-piper-en-with-callback.sh:17,
run-non-streaming-tts-piper-en.sh:17, run-non-streaming-tts-vits-zh.sh:17, and
run-non-streaming-websocket-client.sh:13, preserving the existing native path
value and Java invocation.

In `@java-api-examples/run-inverse-text-normalization-transducer.sh`:
- Line 22: Quote the $PWD-based native path argument in each listed script so
the complete Java -D argument remains intact when the working directory contains
spaces or glob characters. Apply this change at the native-path invocation in
java-api-examples/run-inverse-text-normalization-transducer.sh#L22-L22,
java-api-examples/run-offline-add-diacritics.sh#L14-L14,
java-api-examples/run-offline-add-punctuation-zh-en.sh#L14-L14,
java-api-examples/run-offline-speaker-diarization.sh#L22-L22,
java-api-examples/run-online-add-punctuation-zh-en.sh#L14-L14,
java-api-examples/run-pocket-tts.sh#L26-L26,
java-api-examples/run-speaker-identification.sh#L18-L18,
java-api-examples/run-spoken-language-identification-whisper.sh#L22-L22,
java-api-examples/run-streaming-asr-from-mic-transducer.sh#L18-L18,
java-api-examples/run-streaming-decode-file-ctc-hlg.sh#L14-L14,
java-api-examples/run-streaming-decode-file-ctc.sh#L14-L14, and
java-api-examples/run-streaming-decode-file-paraformer.sh#L14-L14.

In `@java-api-examples/run-kws-from-file.sh`:
- Line 14: Quote the $PWD-based sherpa_onnx.native.path JVM argument in
java-api-examples/run-kws-from-file.sh:14,
java-api-examples/run-streaming-decode-file-tone-ctc.sh:14,
java-api-examples/run-streaming-decode-file-transducer.sh:14,
java-api-examples/run-streaming-speech-enhancement-dpdfnet.sh:16,
java-api-examples/run-streaming-speech-enhancement-gtcrn.sh:16,
java-api-examples/run-supertonic-tts.sh:18,
java-api-examples/run-ten-vad-remove-silence.sh:16,
java-api-examples/run-vad-from-mic-non-streaming-moonshine.sh:18,
java-api-examples/run-vad-from-mic-non-streaming-paraformer.sh:23,
java-api-examples/run-vad-from-mic-non-streaming-sense-voice.sh:18, and
java-api-examples/run-vad-from-mic-non-streaming-whisper.sh:19, preserving the
existing path value while preventing spaces in $PWD from splitting the JVM
argument.</code>

In `@java-api-examples/run-non-streaming-decode-file-dolphin-ctc.sh`:
- Line 15: Quote the sherpa_onnx.native.path JVM argument in the
run-non-streaming-decode-file-dolphin-ctc.sh command so paths derived from $PWD
remain a single argument when they contain whitespace.

In `@java-api-examples/setup.sh`:
- Line 7: Update the setup guard and native-library copy commands in setup.sh to
validate the complete Windows installation expected by LibraryUtils, including
all required runtime DLLs rather than only sherpa-onnx-jni.dll. Remove the ||
true suppression from required copy operations so missing artifacts fail setup
and trigger rebuilding instead of accepting an incomplete or stale cache.

In `@sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/LibraryUtils.java`:
- Around line 98-111: Initialize OS detection by invoking getOsArch() before the
detectedOS check in the ONNX Runtime loading block. Ensure detectedOS is set
before selecting the macOS-specific libonnxruntime.1.27.0.dylib filename, while
preserving the existing non-macOS System.mapLibraryName flow.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 49fa9bc6-c6a2-4d5e-be51-3001e06d0298

📥 Commits

Reviewing files that changed from the base of the PR and between 881ce30 and c5e2859.

📒 Files selected for processing (84)
  • .github/workflows/jar.yaml
  • .github/workflows/linux-jni-aarch64.yaml
  • .github/workflows/linux-jni.yaml
  • .github/workflows/run-java-test.yaml
  • .github/workflows/windows-arm64-jni.yaml
  • .github/workflows/windows-arm64.yaml
  • .github/workflows/windows-x64-jni.yaml
  • java-api-examples/README.md
  • java-api-examples/gradle-examples/README.md
  • java-api-examples/gradle-examples/build.gradle
  • java-api-examples/gradle-kts-examples/README.md
  • java-api-examples/gradle-kts-examples/build.gradle.kts
  • java-api-examples/maven-examples/README.md
  • java-api-examples/maven-examples/pom.xml
  • java-api-examples/run-audio-tagging-ced-from-file.sh
  • java-api-examples/run-audio-tagging-zipformer-from-file.sh
  • java-api-examples/run-inverse-text-normalization-paraformer.sh
  • java-api-examples/run-inverse-text-normalization-transducer.sh
  • java-api-examples/run-kws-from-file.sh
  • java-api-examples/run-non-streaming-decode-file-cohere-transcribe.sh
  • java-api-examples/run-non-streaming-decode-file-dolphin-ctc.sh
  • java-api-examples/run-non-streaming-decode-file-fire-red-asr-ctc.sh
  • java-api-examples/run-non-streaming-decode-file-fire-red-asr.sh
  • java-api-examples/run-non-streaming-decode-file-funasr-nano.sh
  • java-api-examples/run-non-streaming-decode-file-medasr-ctc.sh
  • java-api-examples/run-non-streaming-decode-file-moonshine-v2.sh
  • java-api-examples/run-non-streaming-decode-file-moonshine.sh
  • java-api-examples/run-non-streaming-decode-file-nemo-canary.sh
  • java-api-examples/run-non-streaming-decode-file-nemo.sh
  • java-api-examples/run-non-streaming-decode-file-omnilingual-asr-ctc.sh
  • java-api-examples/run-non-streaming-decode-file-paraformer.sh
  • java-api-examples/run-non-streaming-decode-file-qwen3-asr.sh
  • java-api-examples/run-non-streaming-decode-file-sense-voice-with-hr.sh
  • java-api-examples/run-non-streaming-decode-file-sense-voice.sh
  • java-api-examples/run-non-streaming-decode-file-tele-speech-ctc.sh
  • java-api-examples/run-non-streaming-decode-file-transducer-hotwords.sh
  • java-api-examples/run-non-streaming-decode-file-transducer.sh
  • java-api-examples/run-non-streaming-decode-file-wenet-ctc.sh
  • java-api-examples/run-non-streaming-decode-file-whisper-multiple.sh
  • java-api-examples/run-non-streaming-decode-file-whisper.sh
  • java-api-examples/run-non-streaming-decode-file-zipformer-ctc.sh
  • java-api-examples/run-non-streaming-speech-enhancement-dpdfnet.sh
  • java-api-examples/run-non-streaming-speech-enhancement-gtcrn.sh
  • java-api-examples/run-non-streaming-tts-coqui-de.sh
  • java-api-examples/run-non-streaming-tts-kitten-en.sh
  • java-api-examples/run-non-streaming-tts-kokoro-en.sh
  • java-api-examples/run-non-streaming-tts-kokoro-zh-en.sh
  • java-api-examples/run-non-streaming-tts-matcha-en.sh
  • java-api-examples/run-non-streaming-tts-matcha-zh.sh
  • java-api-examples/run-non-streaming-tts-piper-en-with-callback.sh
  • java-api-examples/run-non-streaming-tts-piper-en.sh
  • java-api-examples/run-non-streaming-tts-vits-zh.sh
  • java-api-examples/run-non-streaming-websocket-client.sh
  • java-api-examples/run-offline-add-diacritics.sh
  • java-api-examples/run-offline-add-punctuation-zh-en.sh
  • java-api-examples/run-offline-speaker-diarization.sh
  • java-api-examples/run-online-add-punctuation-zh-en.sh
  • java-api-examples/run-pocket-tts.sh
  • java-api-examples/run-speaker-identification.sh
  • java-api-examples/run-spoken-language-identification-whisper.sh
  • java-api-examples/run-streaming-asr-from-mic-transducer.sh
  • java-api-examples/run-streaming-decode-file-ctc-hlg.sh
  • java-api-examples/run-streaming-decode-file-ctc.sh
  • java-api-examples/run-streaming-decode-file-paraformer.sh
  • java-api-examples/run-streaming-decode-file-tone-ctc.sh
  • java-api-examples/run-streaming-decode-file-transducer.sh
  • java-api-examples/run-streaming-speech-enhancement-dpdfnet.sh
  • java-api-examples/run-streaming-speech-enhancement-gtcrn.sh
  • java-api-examples/run-supertonic-tts.sh
  • java-api-examples/run-ten-vad-remove-silence.sh
  • java-api-examples/run-vad-from-mic-non-streaming-moonshine.sh
  • java-api-examples/run-vad-from-mic-non-streaming-paraformer.sh
  • java-api-examples/run-vad-from-mic-non-streaming-sense-voice.sh
  • java-api-examples/run-vad-from-mic-non-streaming-whisper.sh
  • java-api-examples/run-vad-from-mic.sh
  • java-api-examples/run-vad-non-streaming-dolphin-ctc.sh
  • java-api-examples/run-vad-non-streaming-paraformer.sh
  • java-api-examples/run-vad-non-streaming-sense-voice.sh
  • java-api-examples/run-vad-remove-silence.sh
  • java-api-examples/run-version-test.sh
  • java-api-examples/run-zipvoice-tts.sh
  • java-api-examples/setup.sh
  • jitpack.yml
  • sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/LibraryUtils.java

repo_name: k2-fsa/sherpa-onnx
repo_token: ${{ secrets.UPLOAD_GH_SHERPA_ONNX_TOKEN }}
tag: v1.12.25
tag: v1.13.4

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked workflow files:"
git ls-files '.github/workflows/*.yaml' | sort

for f in .github/workflows/linux-jni-aarch64.yaml .github/workflows/linux-jni.yaml .github/workflows/windows-x64-jni.yaml; do
  echo
  echo "===== $f ====="
  wc -l "$f"
  rg -n "pull_request_target|pull_request|push|refs/tags|tag:|gh release|upload|github.ref_name|workflow_dispatch|release" "$f" -C 3 || true
done

Repository: k2-fsa/sherpa-onnx

Length of output: 17415


Use the pushed tag for fork-to-canonical release uploads.

These workflows trigger on any v*.*.* tag push from the fork, but the release steps still upload to hard-coded v1.13.4 releases in k2-fsa/sherpa-onnx. Use tag: ${{ github.ref_name }} for the canonical release paths, or restrict those steps/triggers to v1.13.4.

  • .github/workflows/linux-jni-aarch64.yaml#L184: dynamic tag for the fork release path.
  • .github/workflows/linux-jni.yaml#L203: dynamic tag for the fork release path.
  • .github/workflows/windows-x64-jni.yaml#L105: dynamic tag for the fork release path.
📍 Affects 3 files
  • .github/workflows/linux-jni-aarch64.yaml#L184-L184 (this comment)
  • .github/workflows/linux-jni.yaml#L203-L203
  • .github/workflows/windows-x64-jni.yaml#L105-L105
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/linux-jni-aarch64.yaml at line 184, Replace the hard-coded
v1.13.4 release tag with the pushed tag expression github.ref_name in the fork
release paths at .github/workflows/linux-jni-aarch64.yaml:184,
.github/workflows/linux-jni.yaml:203, and
.github/workflows/windows-x64-jni.yaml:105, preserving the existing release
upload behavior.

Comment on lines +26 to +28
- uses: actions/checkout@v4
with:
fetch-depth: 0

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Persist-credentials should be disabled on checkout.

actions/checkout@v4 defaults to persisting the GITHUB_TOKEN in the local git config, which stays exposed to every subsequent step (including third-party actions) in this job. None of the later steps need it — the huggingface push and release upload steps use their own explicit tokens.

🔒 Proposed fix
       - uses: actions/checkout@v4
         with:
           fetch-depth: 0
+          persist-credentials: false
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
🧰 Tools
🪛 zizmor (1.26.1)

[warning] 26-28: credential persistence through GitHub Actions artifacts (artipacked): does not set persist-credentials: false

(artipacked)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/windows-arm64-jni.yaml around lines 26 - 28, Update the
actions/checkout@v4 step to disable credential persistence by setting
persist-credentials to false in its with configuration, while preserving
fetch-depth: 0 and the existing workflow steps.

Source: Linters/SAST tools

Comment on lines +76 to +94
- name: Copy files
shell: bash
run: |
SHERPA_ONNX_VERSION=v$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2)

dst=sherpa-onnx-${SHERPA_ONNX_VERSION}-win-arm64-jni
mkdir -p $dst

cp -a build/install/lib $dst/ || true

tar cjvf ${dst}.tar.bz2 $dst

- name: Release pre-compiled binaries and libs for Windows arm64
if: github.repository_owner == 'k2-fsa' && github.event_name == 'push' && contains(github.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2
with:
file_glob: true
overwrite: true
file: sherpa-onnx-*.tar.bz2

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Silent failure on library copy can ship a broken release archive.

cp -a build/install/lib $dst/ || true swallows any copy failure. If build/install/lib is missing/incomplete, the script still proceeds to tar an empty/partial $dst and later upload it as a release artifact and to Hugging Face, with no CI failure signal.

🛠️ Proposed fix
-          cp -a build/install/lib $dst/ || true
+          cp -a build/install/lib $dst/
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
- name: Copy files
shell: bash
run: |
SHERPA_ONNX_VERSION=v$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2)
dst=sherpa-onnx-${SHERPA_ONNX_VERSION}-win-arm64-jni
mkdir -p $dst
cp -a build/install/lib $dst/ || true
tar cjvf ${dst}.tar.bz2 $dst
- name: Release pre-compiled binaries and libs for Windows arm64
if: github.repository_owner == 'k2-fsa' && github.event_name == 'push' && contains(github.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2
with:
file_glob: true
overwrite: true
file: sherpa-onnx-*.tar.bz2
- name: Copy files
shell: bash
run: |
SHERPA_ONNX_VERSION=v$(grep "SHERPA_ONNX_VERSION" ./CMakeLists.txt | cut -d " " -f 2 | cut -d '"' -f 2)
dst=sherpa-onnx-${SHERPA_ONNX_VERSION}-win-arm64-jni
mkdir -p $dst
cp -a build/install/lib $dst/
tar cjvf ${dst}.tar.bz2 $dst
- name: Release pre-compiled binaries and libs for Windows arm64
if: github.repository_owner == 'k2-fsa' && github.event_name == 'push' && contains(github.ref, 'refs/tags/')
uses: svenstaro/upload-release-action@v2
with:
file_glob: true
overwrite: true
file: sherpa-onnx-*.tar.bz2
🧰 Tools
🪛 zizmor (1.26.1)

[info] 90-90: action functionality is already included by the runner (superfluous-actions): use gh release create and gh release upload in a script step

(superfluous-actions)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/windows-arm64-jni.yaml around lines 76 - 94, Remove the
silent-failure fallback from the library copy command in the “Copy files” step.
Make the copy of build/install/lib into $dst fail the workflow when the source
is missing or the copy is unsuccessful, while preserving the existing archive
creation and release-upload flow for successful copies.


java \
-Djava.library.path=$PWD/../build/lib \
-Dsherpa_onnx.native.path=$PWD/../build/lib \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Tracked launcher files matching concern:"
git ls-files 'java-api-examples/run-*.sh' | sort | sed -n '1,120p'

echo
echo "Matching native path lines:"
rg -n '\-Dsherpa_onnx\.native\.path=\$PWD/../build/lib \\?' java-api-examples || true

echo
echo "Relevant shell parsing behavior probe for unquoted/expansion in argument assignment-like line:"
python3 - <<'PY'
inputs = [
    "-Dsherpa_onnx.native.path=$PWD/../build/lib",
    '-Dsherpa_onnx.native.path="$PWD/../build/lib"',
]
# Show raw tokens after Bash-like command parsing/word-splitting if PATH is unset/not expanded.
# Use Python's shlex only shows whitespace splitting/quoting, not $PWD expansion; demonstrate argument count.
print("raw line count split by whitespace:")
for line in inputs:
    print(repr(line), "=>", line.split())
PY

Repository: k2-fsa/sherpa-onnx

Length of output: 11656


Quote $PWD in every native-path JVM argument.

These Java example launchers pass ...path=$PWD/../build/lib unquoted, so a checkout path containing spaces is split and Java receives a malformed system property plus an extra argument.

Replace each occurrence with ...path="$PWD/../build/lib" across the affected launchers.

🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 14-14: Double quote to prevent globbing and word splitting.

(SC2086)

📍 Affects 11 files
  • java-api-examples/run-audio-tagging-ced-from-file.sh#L14-L14 (this comment)
  • java-api-examples/run-non-streaming-decode-file-fire-red-asr-ctc.sh#L15-L15
  • java-api-examples/run-non-streaming-decode-file-fire-red-asr.sh#L15-L15
  • java-api-examples/run-non-streaming-decode-file-funasr-nano.sh#L14-L14
  • java-api-examples/run-non-streaming-decode-file-medasr-ctc.sh#L15-L15
  • java-api-examples/run-non-streaming-decode-file-moonshine-v2.sh#L14-L14
  • java-api-examples/run-non-streaming-decode-file-moonshine.sh#L14-L14
  • java-api-examples/run-non-streaming-decode-file-nemo-canary.sh#L14-L14
  • java-api-examples/run-non-streaming-decode-file-nemo.sh#L14-L14
  • java-api-examples/run-non-streaming-decode-file-omnilingual-asr-ctc.sh#L15-L15
  • java-api-examples/run-non-streaming-decode-file-paraformer.sh#L15-L15
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@java-api-examples/run-audio-tagging-ced-from-file.sh` at line 14, Quote the
$PWD-based native-path JVM argument in every affected launcher so paths
containing spaces remain a single argument:
java-api-examples/run-audio-tagging-ced-from-file.sh:14,
run-non-streaming-decode-file-fire-red-asr-ctc.sh:15,
run-non-streaming-decode-file-fire-red-asr.sh:15,
run-non-streaming-decode-file-funasr-nano.sh:14,
run-non-streaming-decode-file-medasr-ctc.sh:15,
run-non-streaming-decode-file-moonshine-v2.sh:14,
run-non-streaming-decode-file-moonshine.sh:14,
run-non-streaming-decode-file-nemo-canary.sh:14,
run-non-streaming-decode-file-nemo.sh:14,
run-non-streaming-decode-file-omnilingual-asr-ctc.sh:15, and
run-non-streaming-decode-file-paraformer.sh:15. Apply the same quoting to each
native-path value without changing the surrounding launcher behavior.

Source: Linters/SAST tools


java \
-Djava.library.path=$PWD/../build/lib \
-Dsherpa_onnx.native.path=$PWD/../build/lib \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Quote $PWD in every launcher.

If the checkout path contains spaces, Bash splits the unquoted expansion and Java receives a malformed native-path option.

  • java-api-examples/run-audio-tagging-zipformer-from-file.sh#L14-L14: quote the path.
  • java-api-examples/run-non-streaming-decode-file-qwen3-asr.sh#L14-L14: quote the path.
  • java-api-examples/run-non-streaming-decode-file-sense-voice-with-hr.sh#L24-L24: quote the path.
  • java-api-examples/run-non-streaming-decode-file-sense-voice.sh#L14-L14: quote the path.
  • java-api-examples/run-non-streaming-decode-file-tele-speech-ctc.sh#L14-L14: quote the path.
  • java-api-examples/run-non-streaming-decode-file-transducer-hotwords.sh#L20-L20: quote the path.
  • java-api-examples/run-non-streaming-decode-file-transducer.sh#L15-L15: quote the path.
  • java-api-examples/run-non-streaming-decode-file-wenet-ctc.sh#L14-L14: quote the path.
  • java-api-examples/run-non-streaming-decode-file-whisper-multiple.sh#L15-L15: quote the path.
  • java-api-examples/run-non-streaming-decode-file-whisper.sh#L15-L15: quote the path.
  • java-api-examples/run-non-streaming-decode-file-zipformer-ctc.sh#L15-L15: quote the path.
  • java-api-examples/run-non-streaming-speech-enhancement-dpdfnet.sh#L16-L16: quote the path.
Proposed fix
-  -Dsherpa_onnx.native.path=$PWD/../build/lib \
+  "-Dsherpa_onnx.native.path=$PWD/../build/lib" \
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
-Dsherpa_onnx.native.path=$PWD/../build/lib \
"-Dsherpa_onnx.native.path=$PWD/../build/lib" \
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 14-14: Double quote to prevent globbing and word splitting.

(SC2086)

📍 Affects 12 files
  • java-api-examples/run-audio-tagging-zipformer-from-file.sh#L14-L14 (this comment)
  • java-api-examples/run-non-streaming-decode-file-qwen3-asr.sh#L14-L14
  • java-api-examples/run-non-streaming-decode-file-sense-voice-with-hr.sh#L24-L24
  • java-api-examples/run-non-streaming-decode-file-sense-voice.sh#L14-L14
  • java-api-examples/run-non-streaming-decode-file-tele-speech-ctc.sh#L14-L14
  • java-api-examples/run-non-streaming-decode-file-transducer-hotwords.sh#L20-L20
  • java-api-examples/run-non-streaming-decode-file-transducer.sh#L15-L15
  • java-api-examples/run-non-streaming-decode-file-wenet-ctc.sh#L14-L14
  • java-api-examples/run-non-streaming-decode-file-whisper-multiple.sh#L15-L15
  • java-api-examples/run-non-streaming-decode-file-whisper.sh#L15-L15
  • java-api-examples/run-non-streaming-decode-file-zipformer-ctc.sh#L15-L15
  • java-api-examples/run-non-streaming-speech-enhancement-dpdfnet.sh#L16-L16
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@java-api-examples/run-audio-tagging-zipformer-from-file.sh` at line 14, Quote
the $PWD-based native library path in the launcher arguments so checkout paths
containing spaces remain a single Java option. Apply this change to
java-api-examples/run-audio-tagging-zipformer-from-file.sh:14,
java-api-examples/run-non-streaming-decode-file-qwen3-asr.sh:14,
java-api-examples/run-non-streaming-decode-file-sense-voice-with-hr.sh:24,
java-api-examples/run-non-streaming-decode-file-sense-voice.sh:14,
java-api-examples/run-non-streaming-decode-file-tele-speech-ctc.sh:14,
java-api-examples/run-non-streaming-decode-file-transducer-hotwords.sh:20,
java-api-examples/run-non-streaming-decode-file-transducer.sh:15,
java-api-examples/run-non-streaming-decode-file-wenet-ctc.sh:14,
java-api-examples/run-non-streaming-decode-file-whisper-multiple.sh:15,
java-api-examples/run-non-streaming-decode-file-whisper.sh:15,
java-api-examples/run-non-streaming-decode-file-zipformer-ctc.sh:15, and
java-api-examples/run-non-streaming-speech-enhancement-dpdfnet.sh:16.

Source: Linters/SAST tools


java \
-Djava.library.path=$PWD/../build/lib \
-Dsherpa_onnx.native.path=$PWD/../build/lib \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Quote $PWD in every native-path argument.

An unquoted $PWD is split or glob-expanded when the working directory contains spaces or glob characters, causing Java to receive a malformed -D argument. Apply the same fix at every listed site:

-  -Dsherpa_onnx.native.path=$PWD/../build/lib \
+  -Dsherpa_onnx.native.path="$PWD/../build/lib" \
  • java-api-examples/run-inverse-text-normalization-transducer.sh#L22-L22: quote the native path.
  • java-api-examples/run-offline-add-diacritics.sh#L14-L14: quote the native path.
  • java-api-examples/run-offline-add-punctuation-zh-en.sh#L14-L14: quote the native path.
  • java-api-examples/run-offline-speaker-diarization.sh#L22-L22: quote the native path.
  • java-api-examples/run-online-add-punctuation-zh-en.sh#L14-L14: quote the native path.
  • java-api-examples/run-pocket-tts.sh#L26-L26: quote the native path.
  • java-api-examples/run-speaker-identification.sh#L18-L18: quote the native path.
  • java-api-examples/run-spoken-language-identification-whisper.sh#L22-L22: quote the native path.
  • java-api-examples/run-streaming-asr-from-mic-transducer.sh#L18-L18: quote the native path.
  • java-api-examples/run-streaming-decode-file-ctc-hlg.sh#L14-L14: quote the native path.
  • java-api-examples/run-streaming-decode-file-ctc.sh#L14-L14: quote the native path.
  • java-api-examples/run-streaming-decode-file-paraformer.sh#L14-L14: quote the native path.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
-Dsherpa_onnx.native.path=$PWD/../build/lib \
-Dsherpa_onnx.native.path="$PWD/../build/lib" \
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 22-22: Double quote to prevent globbing and word splitting.

(SC2086)

📍 Affects 12 files
  • java-api-examples/run-inverse-text-normalization-transducer.sh#L22-L22 (this comment)
  • java-api-examples/run-offline-add-diacritics.sh#L14-L14
  • java-api-examples/run-offline-add-punctuation-zh-en.sh#L14-L14
  • java-api-examples/run-offline-speaker-diarization.sh#L22-L22
  • java-api-examples/run-online-add-punctuation-zh-en.sh#L14-L14
  • java-api-examples/run-pocket-tts.sh#L26-L26
  • java-api-examples/run-speaker-identification.sh#L18-L18
  • java-api-examples/run-spoken-language-identification-whisper.sh#L22-L22
  • java-api-examples/run-streaming-asr-from-mic-transducer.sh#L18-L18
  • java-api-examples/run-streaming-decode-file-ctc-hlg.sh#L14-L14
  • java-api-examples/run-streaming-decode-file-ctc.sh#L14-L14
  • java-api-examples/run-streaming-decode-file-paraformer.sh#L14-L14
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@java-api-examples/run-inverse-text-normalization-transducer.sh` at line 22,
Quote the $PWD-based native path argument in each listed script so the complete
Java -D argument remains intact when the working directory contains spaces or
glob characters. Apply this change at the native-path invocation in
java-api-examples/run-inverse-text-normalization-transducer.sh#L22-L22,
java-api-examples/run-offline-add-diacritics.sh#L14-L14,
java-api-examples/run-offline-add-punctuation-zh-en.sh#L14-L14,
java-api-examples/run-offline-speaker-diarization.sh#L22-L22,
java-api-examples/run-online-add-punctuation-zh-en.sh#L14-L14,
java-api-examples/run-pocket-tts.sh#L26-L26,
java-api-examples/run-speaker-identification.sh#L18-L18,
java-api-examples/run-spoken-language-identification-whisper.sh#L22-L22,
java-api-examples/run-streaming-asr-from-mic-transducer.sh#L18-L18,
java-api-examples/run-streaming-decode-file-ctc-hlg.sh#L14-L14,
java-api-examples/run-streaming-decode-file-ctc.sh#L14-L14, and
java-api-examples/run-streaming-decode-file-paraformer.sh#L14-L14.

Source: Linters/SAST tools


java \
-Djava.library.path=$PWD/../build/lib \
-Dsherpa_onnx.native.path=$PWD/../build/lib \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf 'Files with native.path containing unquoted $PWD expansion:\n'
rg -n '\-Dsherpa_onnx\.native\.path=.*\$PWD|sherpa_onnx\.native\.path' java-api-examples || true

printf '\nLine context around reported sites:\n'
for f in \
  java-api-examples/run-kws-from-file.sh \
  java-api-examples/run-streaming-decode-file-tone-ctc.sh \
  java-api-examples/run-streaming-decode-file-transducer.sh \
  java-api-examples/run-streaming-speech-enhancement-dpdfnet.sh \
  java-api-examples/run-streaming-speech-enhancement-gtcrn.sh \
  java-api-examples/run-supertonic-tts.sh \
  java-api-examples/run-ten-vad-remove-silence.sh \
  java-api-examples/run-vad-from-mic-non-streaming-moonshine.sh \
  java-api-examples/run-vad-from-mic-non-streaming-paraformer.sh \
  java-api-examples/run-vad-from-mic-non-streaming-sense-voice.sh \
  java-api-examples/run-vad-from-mic-non-streaming-whisper.sh
do
  printf '\n--- %s ---\n' "$f"
  sed -n '1,40p' "$f" | cat -n
done

printf '\nShell argument-splitting simulation for unquoted pwd=\$PWD in ' || true
python3 - <<'PY'
# Simulate Bash's unquoted command-line expansion for a property value that is generated as "$PWD/../build/lib".
# No actual repository code is run; this only models argument separation.
paths = [
    "C:/Program Files/SherpaOnnx/java-api-examples",
    "/home alice/test/sherpa/build",
    "/tmp/no-space-path",
]
for p in paths:
    tokens = f"-Dsherpa_onnx.native.path={p}/../build/lib".split()
    print(f"pwd={p!r} -> unquoted JVM arg count={len(tokens)} values={tokens}")
PY

Repository: k2-fsa/sherpa-onnx

Length of output: 16781


Quote the native-library path argument.

When the checkout path contains spaces, the unquoted $PWD expansion is split into multiple JVM arguments, so the Java process does not receive the intended sherpa_onnx.native.path. Quote the expansion in these launchers, and the same pattern applies to the unchanged variants with the same -D...=$PWD/../build/lib value:

-  -Dsherpa_onnx.native.path=$PWD/../build/lib \
+  -Dsherpa_onnx.native.path="$PWD/../build/lib" \
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
-Dsherpa_onnx.native.path=$PWD/../build/lib \
-Dsherpa_onnx.native.path="$PWD/../build/lib" \
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 14-14: Double quote to prevent globbing and word splitting.

(SC2086)

📍 Affects 11 files
  • java-api-examples/run-kws-from-file.sh#L14-L14 (this comment)
  • java-api-examples/run-streaming-decode-file-tone-ctc.sh#L14-L14
  • java-api-examples/run-streaming-decode-file-transducer.sh#L14-L14
  • java-api-examples/run-streaming-speech-enhancement-dpdfnet.sh#L16-L16
  • java-api-examples/run-streaming-speech-enhancement-gtcrn.sh#L16-L16
  • java-api-examples/run-supertonic-tts.sh#L18-L18
  • java-api-examples/run-ten-vad-remove-silence.sh#L16-L16
  • java-api-examples/run-vad-from-mic-non-streaming-moonshine.sh#L18-L18
  • java-api-examples/run-vad-from-mic-non-streaming-paraformer.sh#L23-L23
  • java-api-examples/run-vad-from-mic-non-streaming-sense-voice.sh#L18-L18
  • java-api-examples/run-vad-from-mic-non-streaming-whisper.sh#L19-L19
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@java-api-examples/run-kws-from-file.sh` at line 14, Quote the $PWD-based
sherpa_onnx.native.path JVM argument in
java-api-examples/run-kws-from-file.sh:14,
java-api-examples/run-streaming-decode-file-tone-ctc.sh:14,
java-api-examples/run-streaming-decode-file-transducer.sh:14,
java-api-examples/run-streaming-speech-enhancement-dpdfnet.sh:16,
java-api-examples/run-streaming-speech-enhancement-gtcrn.sh:16,
java-api-examples/run-supertonic-tts.sh:18,
java-api-examples/run-ten-vad-remove-silence.sh:16,
java-api-examples/run-vad-from-mic-non-streaming-moonshine.sh:18,
java-api-examples/run-vad-from-mic-non-streaming-paraformer.sh:23,
java-api-examples/run-vad-from-mic-non-streaming-sense-voice.sh:18, and
java-api-examples/run-vad-from-mic-non-streaming-whisper.sh:19, preserving the
existing path value while preventing spaces in $PWD from splitting the JVM
argument.</code>

Source: Linters/SAST tools


java \
-Djava.library.path=$PWD/../build/lib \
-Dsherpa_onnx.native.path=$PWD/../build/lib \

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate file =="
git ls-files | grep -F 'run-non-streaming-decode-file-dolphin-ctc.sh' || true

echo "== File excerpt =="
if [ -f java-api-examples/run-non-streaming-decode-file-dolphin-ctc.sh ]; then
  nl -ba java-api-examples/run-non-streaming-decode-file-dolphin-ctc.sh | sed -n '1,80p'
else
  fd -a 'run-non-streaming-decode-file-dolphin-ctc.sh' . | sed -n '1,20p'
fi

echo "== Search for similar java execution patterns/native path =="
rg -n "sherpa_onnx\.native\.path|java-api-examples|java .*-D" . -g '*.sh' -g '*.java' | sed -n '1,120p'

echo "== Bash word-splitting probe for analogous invocation (read-only) =="
cmd='-Dsherpa_onnx.native.path=$PWD/../build/lib'
# shellcheck disable=SC2086
eval set -- $cmd
printf 'count=%s\n' "$#"
printf 'arg1=%s\n' "$1"
for ((i=2;i<=$#;i++)); do
  printf 'arg%d=%s\n' "$i" "${!i}"
done

Repository: k2-fsa/sherpa-onnx

Length of output: 296


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Locate file =="
git ls-files | grep -F 'run-non-streaming-decode-file-dolphin-ctc.sh' || true

echo "== File excerpt =="
if [ -f java-api-examples/run-non-streaming-decode-file-dolphin-ctc.sh ]; then
  cat -n java-api-examples/run-non-streaming-decode-file-dolphin-ctc.sh | sed -n '1,80p'
fi

echo "== Search for similar java execution patterns/native path =="
rg -n "sherpa_onnx\.native\.path|java-api-examples|java .*-D" . -g '*.sh' -g '*.java' | sed -n '1,120p'

echo "== Bash word-splitting probe for analogous invocation (read-only) =="
cmd='-Dsherpa_onnx.native.path=$PWD/../build/lib'
eval set -- $cmd
printf 'count=%s\n' "$#"
printf 'arg1=%s\n' "$1"
for ((i=2;i<=$#;i++)); do
  printf 'arg%d=%s\n' "$i" "${!i}"
done

echo "== Bash word-splitting probe with whitespace path and same invocation pattern =="
tmp='/tmp/with space'
mkdir -p "$tmp"
cd "$tmp"
mkdir -p build/lib
cmd='-Dsherpa_onnx.native.path=\$PWD/../build/lib'
# shellcheck disable=SC2296
eval set -- "$cmd"
printf 'cmd_expanded_count=%s\n' "$#"
printf 'arg1=%s\n' "$1"
if [ "$#" -gt 1 ]; then printf 'arg2=%s\n' "$2"; fi

Repository: k2-fsa/sherpa-onnx

Length of output: 12287


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Java class loading implementation =="
if [ -f sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/LibraryUtils.java ]; then
  cat -n sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/LibraryUtils.java | sed -n '1,110p'
fi

echo "== Dynamic library file patterns under repository build/native locations if present =="
git ls-files | grep -E '(^|/)native-lib/(.*\.(so|dylib|dll)$|.*\.h$)' || true

echo "== Java System.load path semantics probe from javadoc/source availability =="
{ javadoc -help >/dev/null 2>&1 && javadoc -help | sed -n '1,20p'; true; } >/dev/null
printf 'java_home=%s\n' "${JAVA_HOME:-not set}"
java -version >/dev/null 2>&1 || true

Repository: k2-fsa/sherpa-onnx

Length of output: 4908


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Bash word-splitting probe matching this script's exact line =="
tmp='/tmp/with space'
mkdir -p "$tmp"
cd "$tmp"
mkdir -p build/lib

# This matches the unquoted property substitution in line 15.
cmd='-Dsherpa_onnx.native.path=$PWD/../build/lib'
eval set -- $cmd
printf 'count=%s\n' "$#"
printf 'arg1=%s\n' "$1"
if [ "$#" -gt 1 ]; then printf 'arg2=%s\n' "$2"; fi
if [ "$#" -gt 2 ]; then printf 'arg3=%s\n' "$3"; fi

echo "== Current script line raw =="
sed -n '14,15p' java-api-examples/run-non-streaming-decode-file-dolphin-ctc.sh

Repository: k2-fsa/sherpa-onnx

Length of output: 431


Quote the native-path argument.

If $PWD contains whitespace, -Dsherpa_onnx.native.path=$PWD/../build/lib is word-split so Java receives separate -D values instead of the intended sherpa_onnx.native.path.

Proposed fix
-  -Dsherpa_onnx.native.path=$PWD/../build/lib
+  -Dsherpa_onnx.native.path="$PWD/../build/lib"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
-Dsherpa_onnx.native.path=$PWD/../build/lib \
-Dsherpa_onnx.native.path="$PWD/../build/lib" \
🧰 Tools
🪛 Shellcheck (0.11.0)

[info] 15-15: Double quote to prevent globbing and word splitting.

(SC2086)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@java-api-examples/run-non-streaming-decode-file-dolphin-ctc.sh` at line 15,
Quote the sherpa_onnx.native.path JVM argument in the
run-non-streaming-decode-file-dolphin-ctc.sh command so paths derived from $PWD
remain a single argument when they contain whitespace.

Source: Linters/SAST tools


# Build sherpa-onnx C++ library if not exists
if [[ ! -f ../build/lib/libsherpa-onnx-jni.dylib && ! -f ../build/lib/libsherpa-onnx-jni.so ]]; then
if [[ ! -f ../build/lib/libsherpa-onnx-jni.dylib && ! -f ../build/lib/libsherpa-onnx-jni.so && ! -f ../build/lib/sherpa-onnx-jni.dll ]]; then

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Fail setup when the Windows native installation is incomplete.

The guard treats any existing sherpa-onnx-jni.dll as a complete installation, while the new copy commands suppress missing-artifact errors with || true. A stale JNI DLL or a missing runtime dependency can therefore skip rebuilding and leave every Java example failing during native-library loading. Validate the required installed DLL set before accepting the cache, and let required-copy failures propagate.

🛠️ Proposed direction
-    cp -v ../build/install/lib/*.dll ../build/lib/ 2>/dev/null || true
+    cp -v ../build/install/lib/*.dll ../build/lib/

Also make the existence guard verify the runtime DLLs required by LibraryUtils, not only the JNI DLL.

Also applies to: 17-29

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@java-api-examples/setup.sh` at line 7, Update the setup guard and
native-library copy commands in setup.sh to validate the complete Windows
installation expected by LibraryUtils, including all required runtime DLLs
rather than only sherpa-onnx-jni.dll. Remove the || true suppression from
required copy operations so missing artifacts fail setup and trigger rebuilding
instead of accepting an incomplete or stale cache.

Comment on lines +98 to +111
// Load onnxruntime first to avoid picking up a system version
if (Objects.equals(detectedOS, "osx")) {
File onnxruntimeFile = new File(nativeDir, "libonnxruntime.1.27.0.dylib");
if (onnxruntimeFile.exists()) {
System.load(onnxruntimeFile.getAbsolutePath());
}
} else {
String onnxLibFileName = System.mapLibraryName("onnxruntime");
File onnxruntimeFile = new File(nativeDir, onnxLibFileName);
if (onnxruntimeFile.exists()) {
System.load(onnxruntimeFile.getAbsolutePath());
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Initialize OS detection before selecting the ONNX Runtime filename.

detectedOS is only set by getOsArch(), but this path runs before resource loading invokes it. On macOS, Line 99 therefore evaluates false and looks for libonnxruntime.dylib instead of the packaged libonnxruntime.1.27.0.dylib, causing the subsequently loaded JNI library to miss its intended dependency.

Proposed fix
     private static boolean loadFromSherpaOnnxNativePath() {
+        getOsArch(); // Initializes detectedOS for platform-specific dependency loading.
         String libFileName = System.mapLibraryName(LIB_NAME);
         String nativePath = System.getProperty(NATIVE_PATH_PROP);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Load onnxruntime first to avoid picking up a system version
if (Objects.equals(detectedOS, "osx")) {
File onnxruntimeFile = new File(nativeDir, "libonnxruntime.1.27.0.dylib");
if (onnxruntimeFile.exists()) {
System.load(onnxruntimeFile.getAbsolutePath());
}
} else {
String onnxLibFileName = System.mapLibraryName("onnxruntime");
File onnxruntimeFile = new File(nativeDir, onnxLibFileName);
if (onnxruntimeFile.exists()) {
System.load(onnxruntimeFile.getAbsolutePath());
}
}
private static boolean loadFromSherpaOnnxNativePath() {
getOsArch(); // Initializes detectedOS for platform-specific dependency loading.
String libFileName = System.mapLibraryName(LIB_NAME);
String nativePath = System.getProperty(NATIVE_PATH_PROP);
🧰 Tools
🪛 ast-grep (0.44.1)

[warning] 99-99: Prevent path traversal
Context: new File(nativeDir, "libonnxruntime.1.27.0.dylib")
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'). Security best practice.

(path-traversal-java)


[warning] 105-105: Prevent path traversal
Context: new File(nativeDir, onnxLibFileName)
Note: [CWE-22] Improper Limitation of a Pathname to a Restricted Directory ('Path Traversal'). Security best practice.

(path-traversal-java)

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@sherpa-onnx/java-api/src/main/java/com/k2fsa/sherpa/onnx/LibraryUtils.java`
around lines 98 - 111, Initialize OS detection by invoking getOsArch() before
the detectedOS check in the ONNX Runtime loading block. Ensure detectedOS is set
before selecting the macOS-specific libonnxruntime.1.27.0.dylib filename, while
preserving the existing non-macOS System.mapLibraryName flow.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:M This PR changes 30-99 lines, ignoring generated files.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant