diff --git a/CHANGELOG.md b/CHANGELOG.md index 41d843f..c37ed8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,15 @@ All notable changes to this project are documented here. Format loosely follows [Keep a Changelog](https://keepachangelog.com/); versions are released as `v*` git tags, which trigger publication to Maven Central. +## [0.8] + +### Added +- `module-info.java`: `zstd` now ships as a named JPMS module + (`module io.github.dfa1.zstd`), exporting the single public API package. + Module-path consumers grant `--enable-native-access=io.github.dfa1.zstd` + instead of `ALL-UNNAMED`; classpath consumers are unaffected. See + [ADR 0011](adr/0011-jpms-module-descriptor.md). + ## [0.7] - 2026-06-28 ### Changed diff --git a/adr/0011-jpms-module-descriptor.md b/adr/0011-jpms-module-descriptor.md index 1dfcaf5..72f0c8e 100644 --- a/adr/0011-jpms-module-descriptor.md +++ b/adr/0011-jpms-module-descriptor.md @@ -1,6 +1,6 @@ # ADR 0011: JPMS module descriptor -- **Status:** Proposed +- **Status:** Accepted - **Date:** 2026-06-27 - **Deciders:** project maintainer diff --git a/adr/ADR.md b/adr/ADR.md index 260ff45..52ff27a 100644 --- a/adr/ADR.md +++ b/adr/ADR.md @@ -29,7 +29,7 @@ shipped, so contributors can see *why* the project looks the way it does. | 0008 | `size_t` maps to `JAVA_LONG`, guard sentinels | Accepted | | 0009 | `NativeObject`: AutoCloseable, idempotent close | Accepted | | 0010 | Bounded native-context pool for virtual threads | Proposed | -| 0011 | JPMS module descriptor | Proposed | +| 0011 | JPMS module descriptor | Accepted | | 0012 | Benchmark methodology and publishing | Proposed | | 0013 | Binding coverage scope — exclude legacy/deprecated | Accepted | | 0014 | Single-threaded native build (no `nbWorkers`) | Accepted | diff --git a/docs/reference.md b/docs/reference.md index e63fa7a..276e39b 100644 --- a/docs/reference.md +++ b/docs/reference.md @@ -30,8 +30,18 @@ with a per-area breakdown and a comparison against zstd-jni: ## Runtime requirement -Native access requires `--enable-native-access=ALL-UNNAMED` (or your module name) -on the JVM command line. +Native access requires a flag on the JVM command line: `--enable-native-access=ALL-UNNAMED` +on the classpath, or `--enable-native-access=io.github.dfa1.zstd` on the module path. + +## Module path + +`zstd` ships a `module-info.java` declaring `module io.github.dfa1.zstd`, which +exports only the public API package (`io.github.dfa1.zstd`). The native library +still comes from the separate `zstd-native-` artifact, loaded at +runtime — it is not itself a JPMS module. Putting the jar on the classpath +instead of the module path works unchanged (it becomes part of the unnamed +module and the descriptor is ignored). See +[ADR 0011](../adr/0011-jpms-module-descriptor.md) for the design rationale. ## Build from source diff --git a/zstd/src/main/java/io/github/dfa1/zstd/NativeLibrary.java b/zstd/src/main/java/io/github/dfa1/zstd/NativeLibrary.java index 6baac1b..38ca444 100644 --- a/zstd/src/main/java/io/github/dfa1/zstd/NativeLibrary.java +++ b/zstd/src/main/java/io/github/dfa1/zstd/NativeLibrary.java @@ -42,9 +42,14 @@ static MethodHandle lookup(String name, FunctionDescriptor fd) { private static String extractBundledLib() { String classifier = classifier(); String ext = libExtension(classifier); - String resource = "/native/" + classifier + "/libzstd." + ext; + // Load through the class loader (no leading slash), not Class#getResourceAsStream: + // the library lives in a separate zstd-native- module, and a named + // module only finds resources in itself. The classifier directory name contains a + // dash, so it is not a valid package and the resource is not module-encapsulated — + // the class loader can read it across modules (and on the classpath alike). + String resource = "native/" + classifier + "/libzstd." + ext; - try (InputStream in = NativeLibrary.class.getResourceAsStream(resource)) { + try (InputStream in = NativeLibrary.class.getClassLoader().getResourceAsStream(resource)) { if (in == null) { throw new UnsatisfiedLinkError("No bundled zstd library found for platform " + classifier); } diff --git a/zstd/src/main/java/module-info.java b/zstd/src/main/java/module-info.java new file mode 100644 index 0000000..9ea4742 --- /dev/null +++ b/zstd/src/main/java/module-info.java @@ -0,0 +1,13 @@ +/// Java Foreign Function & Memory (FFM) bindings for Zstandard. +/// +/// Exports the single public API package; the native `libzstd` is loaded at +/// runtime from the platform `zstd-native-` artifact on the path. +/// Requires `--enable-native-access=io.github.dfa1.zstd` (or `ALL-UNNAMED` on +/// the classpath) since FFM downcalls are a restricted operation. +// The "dfa1" component ends in a digit, which the module-name lint flags as +// possibly version-like. It mirrors the Sonatype-verified io.github.dfa1 +// namespace and the package name, so suppress the advisory rather than diverge. +@SuppressWarnings("module") +module io.github.dfa1.zstd { + exports io.github.dfa1.zstd; +}