close
Skip to content

Use virtual threads by default on Java 21+ #56

@brunoborges

Description

@brunoborges

Summary

When running on Java 21+, the SDK should default to using virtual threads instead of platform threads for its internal thread pools and thread creation.

Motivation

Virtual threads (JEP 444, finalized in Java 21) are lightweight threads that can significantly reduce resource usage for I/O-bound workloads like the JSON-RPC communication this SDK performs. Since the SDK targets Java 17+, we can use Multi-Release JARs (JEP 238) to provide a Java 21+ implementation that uses virtual threads while keeping the Java 17 baseline implementation with platform threads.

Current thread usage

The SDK currently creates platform threads in several places:

  • JsonRpcClientExecutors.newSingleThreadExecutor() for the JSON-RPC reader loop, plus a Thread(r, "jsonrpc-reader") factory
  • CopilotSessionScheduledExecutorService for sendAndWait timeouts, plus Thread(r, "sendAndWait-timeout") factory
  • CliServerManagerThread for stderr forwarding

Proposed approach

  1. Create a ThreadFactoryProvider (or similar) abstraction in src/main/java/ that returns standard platform-thread factories (the Java 17 baseline)
  2. Create a Java 21+ override in src/main/java21/ that returns virtual-thread factories (Thread.ofVirtual().factory())
  3. Configure the Maven build to produce a multi-release JAR with the Java 21 classes under META-INF/versions/21/
  4. Replace direct new Thread() and Executors.newSingleThreadExecutor() calls with the factory abstraction

Build conditionality

The second maven-compiler-plugin execution (compiling src/main/java21/ with --release 21 and multiReleaseOutput=true) should be gated by a <jdk>[21,)</jdk> Maven profile so the project still builds cleanly on JDK 17 — the JAR just won't include the MR overlay. CI and release builds should use JDK 21+ to produce the full multi-release JAR.

ScheduledThreadPoolExecutor stays with platform threads

The JDK has no virtual-thread-based ScheduledExecutorService. The ScheduledThreadPoolExecutor in CopilotSession (used for sendAndWait timeouts) should remain with platform threads and is out of scope for this issue.

Spotless coverage for src/main/java21/

The Spotless plugin config needs an explicit include for src/main/java21/**/*.java so the Java 21 override class gets formatted consistently.

Documentation

Ensure that the following documentation is updated to clearly describe virtual threads support when running on Java 21+:

  • README.md — Add a section or note about automatic virtual thread usage on Java 21+, and any configuration/opt-out if applicable
  • Quick Start guide (src/site/markdown/) — Mention virtual threads as a benefit of running on Java 21+ in the getting started flow
  • Examples (e.g., jbang-example.java) — Ensure examples work seamlessly on both Java 17 (platform threads) and Java 21+ (virtual threads), and add comments or notes highlighting the behavior difference
  • Site docs (src/site/markdown/) — Add a dedicated section or page covering virtual threads support: what it means for users, performance implications, and any caveats (e.g., ScheduledExecutorService remaining on platform threads)
  • Javadoc — Document thread behavior on relevant public APIs (e.g., CopilotClient, CopilotSession) so users understand which threads are used at runtime

Notes

  • The ScheduledExecutorService in CopilotSession does not have a virtual-thread equivalent in the JDK — it may need to stay as-is or use an alternative scheduling approach
  • Virtual threads should use the default ForkJoinPool carrier; no custom carrier pool is needed
  • Ensure thread names are preserved for debuggability (Thread.ofVirtual().name("jsonrpc-reader"))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions