This is a bring-up branch to validate JPDFium consumption across all
Stirling-PDF release targets (server jar, Docker, Tauri desktop). Open
as PR for cross-platform CI validation.
Source dep
- com.stirling:jpdfium:1.0.0-SNAPSHOT (pulled from Maven Central snapshots,
fully anonymous — no PAT or GitHub Packages auth needed)
- Per-platform natives: linux-x64, linux-arm64, darwin-arm64, windows-x64
All four are added as runtimeOnly so the bootJar carries every platform
and NativeLoader picks the right one at startup. The natives jars are
hermetic — each bundles its bridge, PDFium component libs, and the
third-party deps (pcre2/freetype/harfbuzz/icu/qpdf/pugixml/libunibreak),
so no system package install is required at runtime.
- TODO follow-up: jpdfium-natives-darwin-x64 (Intel Mac) — dropped from
the upstream publish matrix while cross-compile-on-macos-14 setup lands.
JDK 25 enforcement
- Bump root + subprojects from sourceCompatibility / targetCompatibility
21 -> 25. JPDFium publishes with org.gradle.jvm.version=25 (FFM is final
in JDK 22+; JPDFium picks 25 as the floor), and a 21-targeted Stirling-PDF
jar would fail Gradle's variant attribute match at compile time.
- bootRun jvmArgs: add --enable-native-access=ALL-UNNAMED. JDK 25 warns
on restricted FFM methods without it; JDK 26 will hard-fail.
Docker
- scripts/init-without-ocr.sh: prepend --enable-native-access=ALL-UNNAMED
to JAVA_BASE_OPTS so the JAVA_TOOL_OPTIONS env var that the container
sets includes it for the running JVM. Idempotent — won't duplicate if
already present.
Tauri
- frontend/src-tauri/src/commands/backend.rs: the sidecar Java spawn now
passes --enable-native-access=ALL-UNNAMED. The bundled jlink JRE's
module list (desktop.yml JLINK_MODULES) already includes java.desktop
and java.net.http which is everything JPDFium's module-info requires.
Smoke test
- app/common/src/test/java/stirling/software/common/jpdfium/JPDFiumSmokeTest.java
Opens the existing common test resource example.pdf via PdfDocument.open
and asserts a positive page count. Confirms the dep resolves, the right
natives jar lands on the classpath, the bridge + PDFium component libs
+ third-party deps all load, and the FFM bindings parse a real PDF
end-to-end. Runs as part of :common:test on each platform's CI runner.