Skip to content

One Gradle build, OSGi bundles, one-provider capability, Bouncy Castle upgrade - #33

Merged
scottf merged 1 commit into
mainfrom
osgi-exports
Oct 7, 2026
Merged

scottf merged 1 commit into
mainfrom
osgi-exports

Conversation

@scottf

@scottf scottf commented Oct 7, 2026 •

Copy link
Copy Markdown
Collaborator

OSGi. The jars were OSGi bundles, but nothing exported io.nats.nkey, and the symbolic names were the generic core, lts, fips, regular. Now:

  • core: Bundle-SymbolicName: io.nats.nkeys.core, exports io.nats.nkey.
  • regular, lts, fips: fragments of io.nats.nkeys.core (io.nats.nkeys.regular / .lts / .fips). They put classes in core's package, and NKeyProvider loads the provider class by name through core's class loader, so they have to share core's class loader.

One provider. The implementations contain classes with the same names in the same package (PrivateKeyWrapper, PublicKeyWrapper), so two on a classpath break at runtime. Each implementation now publishes the Gradle capability io.nats.nkeys:nkey-provider; a Gradle build that pulls in two fails with Cannot select module with conflict on capability 'io.nats.nkeys:nkey-provider'. Maven does not read this metadata, so the README now says to use exactly one implementation.

One Gradle build.

  • Root settings.gradle / build.gradle / gradle.properties and one wrapper replace four independent builds. The shared module build is gradle/nkeys-module.gradle; each module's build.gradle is its description and its Bouncy Castle dependency.
  • Implementations depend on project(':core') instead of a pinned published core. The published POM and module metadata depend on core-jdk<tc> at the same version, so core and implementations release together at one version.
  • Published coordinates are unchanged (core-jdk17 ... fips-jdk25).
  • options.release is the target JDK; javadoc errors fail the build; JUnit BOM 5.14.1; mavenCentral() only; the unused bundle task is removed.
  • Workflows: build-pr.yml, build-main.yml, build-release.yml (runs on a GitHub release, as in jnats-json) replace the 10 per-module workflows. Release process change: the core/* and impl/* tags are no longer used; one GitHub release publishes all modules.

Bouncy Castle. bcprov-lts8on 2.73.12.1 → 2.73.13, bcprov-jdk18on 1.85.2 → 1.86. bc-fips 2.1.3 is already the latest. dependencies.md updated.

Verified locally with JDK 21: clean build javadoc for targets 17 and 21 (core 34, regular 21, lts 22, fips 21 tests, all pass; class file versions 61 and 65). Published to a temporary Maven repo and resolved from a consumer build (one implementation resolves; two fail with the capability conflict). In Apache Felix 7.0.5, core + the lts fragment + bcprov-lts8on 2.73.13 + jnats-json (nats-io/jnats-json#40) + the jnats V3 bundles resolve; NKeyProvider.getProvider("io.nats.nkey.LtsNKeyProvider") creates a user key. Target 25 is built by CI only.

🤖 Generated with Claude Code

…e upgrade

- One multi-project build (core, regular, lts, fips) with one wrapper and
  the shared module build in gradle/nkeys-module.gradle; one version in
  gradle.properties. Implementations depend on project(':core'), so core
  and implementations release together at one version.
- OSGi: core has the symbolic name io.nats.nkeys.core and exports
  io.nats.nkey; regular, lts and fips are fragments of it, since they
  share the package and NKeyProvider loads the provider by name.
- Implementations publish the capability io.nats.nkeys:nkey-provider, so
  Gradle fails resolution when two are in one build. README note added.
- bcprov-lts8on 2.73.13, bcprov-jdk18on 1.86 (bc-fips 2.1.3 is latest).
- --release per target JDK, javadoc errors fail the build, JUnit BOM
  5.14.1, mavenCentral only, unused bundle task removed.
- Workflows: build-pr, build-main, build-release (GitHub release event)
  replace the 10 per-module workflows.
@synadia-claude-reviewer

synadia-claude-reviewer Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Claude finished @scottf's task in 3m 4s —— View job


Review complete

  • Gather context (PR diff, repo structure)
  • Review Gradle build consolidation
  • Review OSGi manifest/fragment changes
  • Review workflow changes
  • Review dependency/version bumps
  • Post final review summary

This PR touches only build/CI infrastructure (.gradle files, settings.gradle, workflows, docs) — no .java source changes, so correctness risk is concentrated in the Gradle refactor and CI config.

Bug found: .github/workflows/build-release.yml sets on.release.branches: [main], but the release event in GitHub Actions does not support a branches/branches-ignore filter (only push, pull_request, pull_request_target, merge_group, and workflow_run do; release only supports types). An unrecognized key here generally invalidates the whole workflow file, meaning it would never fire on an actual GitHub release — which directly undermines the PR's stated goal of "one GitHub release publishes all modules." Left an inline comment with a suggested fix (drop branches, keep types: [released]).

Things that check out:

  • Capability conflict setup in gradle/nkeys-module.gradle (re-declaring the default capability alongside io.nats.nkeys:nkey-provider on apiElements/runtimeElements) is the correct Gradle pattern for mutually-exclusive implementations.
  • allprojects { ext.targetJavaVersion = ... } in the root build.gradle runs before subproject scripts evaluate, so gradle/nkeys-module.gradle can safely reference targetJavaVersion/targetId.
  • project(':core') + per-module artifactId on the mavenJava publication should let Gradle correctly map the project dependency to core-jdk<tc> in the published POM for regular/lts/fips, keeping JDK variants aligned within a single build invocation (matches the matrixed tc workflow runs).
  • OSGi fragment config (Fragment-Host, Import-Package: "!io.nats.nkey, *") matches the split-package fragment approach described in the PR body, and the author reports it was verified against Apache Felix.
  • Version bumps (bcprov-lts8on 2.73.13, bcprov-jdk18on 1.86) and dependencies.md updates are consistent with the new dependency declarations.

Comment on lines +5 to +8
release:
branches:
- main
types: [released]

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

release is not among the GitHub Actions events that support a branches filter (only push, pull_request, pull_request_target, merge_group, workflow_run do; release only supports types). An unsupported key like this typically makes the whole workflow file invalid, so this workflow would never run on an actual GitHub release — silently breaking the new single-release publish process this PR is built around.

Suggested change
release:
branches:
- main
types: [released]
release:
types: [released]

Fix this →

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Not changing this: the trigger is valid and has not broken any workflow.

nats-io/jnats-json uses exactly the same trigger in build-release.yml (release: with branches: [main] and types: [released]), and that workflow ran successfully on each of its last 5 releases (3.0.6 through 3.1.0, event release). nats-io/nats.java and nats-io/java-nats-server-runner use the same trigger in their release workflows. So an unsupported branches key under release does not invalidate the file.

GitHub does not filter release events by branch, so the branches key has no effect. It is kept for consistency with the other repos.

@scottf
scottf merged commit 9ae4144 into main Oct 7, 2026
15 checks passed
@scottf
scottf deleted the osgi-exports branch October 7, 2026 23:18
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