Skip to content

Commit 513c677

Browse files
dfa1claude
andauthored
feat: add a JPMS module descriptor (#25)
* feat: add a JPMS module descriptor (io.github.dfa1.zstd) - module-info.java exports the single public package. Lets modular consumers `requires io.github.dfa1.zstd` and scope native access with `--enable-native-access=io.github.dfa1.zstd` instead of ALL-UNNAMED. - Suppress the module-name lint: the `dfa1` component ends in a digit (flagged as possibly version-like), but it mirrors the verified io.github.dfa1 namespace and the package, so keep it. - NativeLibrary now loads the bundled library through the class loader (no leading slash) rather than Class#getResourceAsStream: the library lives in a separate zstd-native-<classifier> module and a named module only finds resources in itself. The classifier directory has a dash, so it is not a package and the resource is not module-encapsulated — the class loader reads it across modules and on the classpath alike. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs: changelog + reference.md for the JPMS module descriptor; accept ADR 0011 CHANGELOG.md — 0.8 Added entry for the module-info.java change. docs/reference.md — spell out the module-path native-access flag (--enable-native-access=io.github.dfa1.zstd) and add a Module path section describing the export surface and classpath fallback. adr/0011-jpms-module-descriptor.md, adr/ADR.md — flip status Proposed -> Accepted now that the descriptor is implemented. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 657e5c1 commit 513c677

6 files changed

Lines changed: 43 additions & 6 deletions

File tree

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,15 @@ All notable changes to this project are documented here. Format loosely follows
44
[Keep a Changelog](https://keepachangelog.com/); versions are released as `v*`
55
git tags, which trigger publication to Maven Central.
66

7+
## [0.8]
8+
9+
### Added
10+
- `module-info.java`: `zstd` now ships as a named JPMS module
11+
(`module io.github.dfa1.zstd`), exporting the single public API package.
12+
Module-path consumers grant `--enable-native-access=io.github.dfa1.zstd`
13+
instead of `ALL-UNNAMED`; classpath consumers are unaffected. See
14+
[ADR 0011](adr/0011-jpms-module-descriptor.md).
15+
716
## [0.7] - 2026-06-28
817

918
### Changed

adr/0011-jpms-module-descriptor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# ADR 0011: JPMS module descriptor
22

3-
- **Status:** Proposed
3+
- **Status:** Accepted
44
- **Date:** 2026-06-27
55
- **Deciders:** project maintainer
66

adr/ADR.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ shipped, so contributors can see *why* the project looks the way it does.
2929
| 0008 | `size_t` maps to `JAVA_LONG`, guard sentinels | Accepted |
3030
| 0009 | `NativeObject`: AutoCloseable, idempotent close | Accepted |
3131
| 0010 | Bounded native-context pool for virtual threads | Proposed |
32-
| 0011 | JPMS module descriptor | Proposed |
32+
| 0011 | JPMS module descriptor | Accepted |
3333
| 0012 | Benchmark methodology and publishing | Proposed |
3434
| 0013 | Binding coverage scope — exclude legacy/deprecated | Accepted |
3535
| 0014 | Single-threaded native build (no `nbWorkers`) | Accepted |

docs/reference.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,18 @@ with a per-area breakdown and a comparison against zstd-jni:
3030

3131
## Runtime requirement
3232

33-
Native access requires `--enable-native-access=ALL-UNNAMED` (or your module name)
34-
on the JVM command line.
33+
Native access requires a flag on the JVM command line: `--enable-native-access=ALL-UNNAMED`
34+
on the classpath, or `--enable-native-access=io.github.dfa1.zstd` on the module path.
35+
36+
## Module path
37+
38+
`zstd` ships a `module-info.java` declaring `module io.github.dfa1.zstd`, which
39+
exports only the public API package (`io.github.dfa1.zstd`). The native library
40+
still comes from the separate `zstd-native-<classifier>` artifact, loaded at
41+
runtime — it is not itself a JPMS module. Putting the jar on the classpath
42+
instead of the module path works unchanged (it becomes part of the unnamed
43+
module and the descriptor is ignored). See
44+
[ADR 0011](../adr/0011-jpms-module-descriptor.md) for the design rationale.
3545

3646
## Build from source
3747

zstd/src/main/java/io/github/dfa1/zstd/NativeLibrary.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,9 +42,14 @@ static MethodHandle lookup(String name, FunctionDescriptor fd) {
4242
private static String extractBundledLib() {
4343
String classifier = classifier();
4444
String ext = libExtension(classifier);
45-
String resource = "/native/" + classifier + "/libzstd." + ext;
45+
// Load through the class loader (no leading slash), not Class#getResourceAsStream:
46+
// the library lives in a separate zstd-native-<classifier> module, and a named
47+
// module only finds resources in itself. The classifier directory name contains a
48+
// dash, so it is not a valid package and the resource is not module-encapsulated —
49+
// the class loader can read it across modules (and on the classpath alike).
50+
String resource = "native/" + classifier + "/libzstd." + ext;
4651

47-
try (InputStream in = NativeLibrary.class.getResourceAsStream(resource)) {
52+
try (InputStream in = NativeLibrary.class.getClassLoader().getResourceAsStream(resource)) {
4853
if (in == null) {
4954
throw new UnsatisfiedLinkError("No bundled zstd library found for platform " + classifier);
5055
}
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
/// Java Foreign Function & Memory (FFM) bindings for Zstandard.
2+
///
3+
/// Exports the single public API package; the native `libzstd` is loaded at
4+
/// runtime from the platform `zstd-native-<classifier>` artifact on the path.
5+
/// Requires `--enable-native-access=io.github.dfa1.zstd` (or `ALL-UNNAMED` on
6+
/// the classpath) since FFM downcalls are a restricted operation.
7+
// The "dfa1" component ends in a digit, which the module-name lint flags as
8+
// possibly version-like. It mirrors the Sonatype-verified io.github.dfa1
9+
// namespace and the package name, so suppress the advisory rather than diverge.
10+
@SuppressWarnings("module")
11+
module io.github.dfa1.zstd {
12+
exports io.github.dfa1.zstd;
13+
}

0 commit comments

Comments
 (0)