build(java): Java 25 for Micronaut libs, Java 17 elsewhere; drop virtual-thread default; fix api leak#94
Merged
Conversation
Remove the shared virtual-thread executor default (Executors.newVirtualThread- PerTaskExecutor, a JDK 21 API) from AbstractWorkQueue and AbstractMessageStream. Handlers now run on an executor supplied via withHandlerExecutor(), which is mandatory - startProcessing() fails fast if none was set. This drops the only Java 21 dependency in these modules, so they compile and run on Java 17. Micronaut consumers already inject the @nAmed(BLOCKING) executor before adding a consumer; test fixtures inject a shared daemon pool (TestWorkerPool). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Paolo Di Tommaso <paolo.ditommaso@gmail.com>
…as api Convention plugins now target Java 17: javac --release 17 (which also caps the API surface to the Java 17 stdlib) and source/target 17 for Groovy. The target is set once in java-library-conventions - applied by every module - to avoid duplicate, order-dependent configureEach across the sibling conventions. Also change lib-cmd-queue-redis's dependency on lib-data-workqueue from implementation to api: CommandQueue publicly extends AbstractWorkQueue and exposes WorkQueue / MessageConsumer, so consumers subclassing it need those types on the compile classpath. It previously resolved only via the published POM's runtime scope and broke Gradle composite builds. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Paolo Di Tommaso <paolo.ditommaso@gmail.com>
Restore the two-convention split (superseding the uniform --release 17 from the
earlier commit). libseqera's toolchain moves to Java 25 and the compile target is
chosen per module type:
- io.seqera.java-library-conventions: plain libraries -> javac --release 17 (+
Groovy source/target 17). These include everything the Nextflow Java 17 runtime
consumes (lib-httpx, lib-retry, lib-trace, wave-api, wave-utils, lib-cloudinfo,
lib-platform-oidc).
- io.seqera.micronaut-library-conventions (new): libraries that depend on
Micronaut -> target Java 25. Micronaut runs on the Java 25 service runtime (and
Micronaut 5 requires Java 25), so these are never loaded on the Nextflow Java 17
runtime. Applied to the 21 Micronaut modules.
Bumps Groovy 4.0.24 -> 4.0.31: the older Groovy cannot run on a JDK 25 toolchain
("Unsupported class file major version 69").
Verified: Micronaut libs compile to bytecode 69 (Java 25), plain libs to 61 (Java
17); full compile and the affected module test suites (incl. Redis testcontainers)
pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Paolo Di Tommaso <paolo.ditommaso@gmail.com>
jordeu
reviewed
Jul 24, 2026
- settings.gradle: add foojay-resolver-convention so the JDK 25 toolchain is auto-provisioned on machines without a local JDK 25 - AbstractWorkQueue/AbstractMessageStream javadoc: usage example now shows the mandatory withHandlerExecutor() call before addConsumer() - workqueue/stream READMEs: drop the stale 'virtual-thread executor by default' wording — the handler executor is injected, no default Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jordeu
approved these changes
Jul 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Split bytecode targeting so libseqera artifacts stay loadable where they are actually consumed, plus two related fixes:
1. Split Java targeting: 25 for Micronaut libs, 17 for the rest
Plain libraries (consumed by the Nextflow Java 17 runtime) compile with
--release 17for javac (which also caps the API surface to the Java 17 stdlib) andsource/target 17for Groovy, set once injava-library-conventions. Micronaut-based libraries target Java 25 viamicronaut-library-conventions: they run only on the Java 25 service runtime (Platform, Wave — the whole stack is being aligned on Java 25). The build toolchain is JDK 25, auto-provisioned via thefoojay-resolver-conventionplugin.2. Drop the virtual-thread executor default
AbstractWorkQueue/AbstractMessageStreampreviously defaulted their handler pool toExecutors.newVirtualThreadPerTaskExecutor()— a JDK 21 API emitted into Java-17 bytecode, i.e. a guaranteedNoSuchMethodErroron a Java 17 runtime. The default is removed; a handler executor must now be supplied viawithHandlerExecutor()before processing (startProcessing()fails fast otherwise). Micronaut consumers already inject the@Named(BLOCKING)executor; test fixtures inject a shared daemon pool.3. Fix an API leak
lib-cmd-queue-redisdepended onlib-data-workqueueasimplementation, butCommandQueuepublicly extendsAbstractWorkQueueand exposesWorkQueue/MessageConsumer. Changed toapiso subclassing consumers get those types on the compile classpath (previously only resolvable via the published POM's runtime scope, which broke Gradle composite builds).Verification
Plain modules emit bytecode 61 (Java 17); Micronaut modules emit bytecode 69 (Java 25). Full test suites pass, including the Redis testcontainers integration tests for the stream/queue/command modules.
🤖 Generated with Claude Code