Skip to content

feat: add a JPMS module descriptor#25

Open
dfa1 wants to merge 1 commit into
mainfrom
feat/jpms-module-info
Open

feat: add a JPMS module descriptor#25
dfa1 wants to merge 1 commit into
mainfrom
feat/jpms-module-info

Conversation

@dfa1

@dfa1 dfa1 commented Jun 26, 2026

Copy link
Copy Markdown
Owner

Make zstd a proper named module: module io.github.dfa1.zstd { exports io.github.dfa1.zstd; }.

Why

Modular consumers can now requires io.github.dfa1.zstd and grant native access to just this module (--enable-native-access=io.github.dfa1.zstd) instead of the blanket ALL-UNNAMED. (The flag is still required either way — FFM downcalls are restricted.)

Notes / gotchas handled

  • Module-name lint. javac flags dfa1 (terminal digit, possibly version-like) and the build uses -Werror. Suppressed with @SuppressWarnings("module") + a comment — it mirrors the Sonatype-verified io.github.dfa1 namespace and the package name, so diverging would be worse.
  • Cross-module native resource. With a module descriptor, the zstd module runs on the module path, where Class#getResourceAsStream only sees its own module — so the bundled libzstd (in a separate zstd-native-<classifier> jar) wasn't found and every test failed with UnsatisfiedLinkError. Fixed by loading through the class loader (no leading slash); the classifier directory name has a dash, so the resource isn't in a package and isn't module-encapsulated → readable across modules and on the classpath alike.

Retest

./mvnw verify (full reactor) — all unit + 79 integration tests green, checkstyle + javadoc clean across all 12 modules. Native library loads on the module path.

Known benign warning: the benchmark JMH uber-jar shade reports "Discovered module-info.class. Shading will break its strong encapsulation" — harmless for the non-published benchmark harness.

🤖 Generated with Claude Code

- 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant