+ * Threading: On Java 21+, the SDK automatically uses virtual threads for + * its internal I/O threads (JSON-RPC reader, CLI stderr forwarding). On Java + * 17–20, standard platform threads are used. The + * {@link java.util.concurrent.ScheduledExecutorService} used for + * {@code sendAndWait} timeouts always uses platform threads because the JDK + * does not provide a virtual-thread-based scheduled executor. + *
* Example usage: * *
{@code
diff --git a/src/main/java/com/github/copilot/sdk/CopilotSession.java b/src/main/java/com/github/copilot/sdk/CopilotSession.java
index 23b1b5368..f35353e4c 100644
--- a/src/main/java/com/github/copilot/sdk/CopilotSession.java
+++ b/src/main/java/com/github/copilot/sdk/CopilotSession.java
@@ -89,6 +89,11 @@
* session data on disk — the conversation can be resumed later via
* {@link CopilotClient#resumeSession}. To permanently delete session data, use
* {@link CopilotClient#deleteSession}.
+ *
+ * Threading: The {@link java.util.concurrent.ScheduledExecutorService}
+ * used for {@code sendAndWait} timeouts always uses platform threads regardless
+ * of the Java version, because the JDK does not provide a virtual-thread-based
+ * scheduled executor.
*
*
Example Usage
*
diff --git a/src/main/java/com/github/copilot/sdk/JsonRpcClient.java b/src/main/java/com/github/copilot/sdk/JsonRpcClient.java
index 66ab1726d..4d16b02d3 100644
--- a/src/main/java/com/github/copilot/sdk/JsonRpcClient.java
+++ b/src/main/java/com/github/copilot/sdk/JsonRpcClient.java
@@ -15,7 +15,6 @@
import java.util.concurrent.CompletionException;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiConsumer;
import java.util.logging.Level;
@@ -57,11 +56,7 @@ private JsonRpcClient(InputStream inputStream, OutputStream outputStream, Socket
this.outputStream = outputStream;
this.socket = socket;
this.process = process;
- this.readerExecutor = Executors.newSingleThreadExecutor(r -> {
- Thread t = new Thread(r, "jsonrpc-reader");
- t.setDaemon(true);
- return t;
- });
+ this.readerExecutor = ThreadFactoryProvider.newSingleThreadExecutor("jsonrpc-reader");
startReader();
}
diff --git a/src/main/java/com/github/copilot/sdk/ThreadFactoryProvider.java b/src/main/java/com/github/copilot/sdk/ThreadFactoryProvider.java
new file mode 100644
index 000000000..3f8ead92b
--- /dev/null
+++ b/src/main/java/com/github/copilot/sdk/ThreadFactoryProvider.java
@@ -0,0 +1,71 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.logging.Logger;
+
+/**
+ * Provides thread factories for the SDK's internal thread creation.
+ *
+ * On Java 17, this class returns standard platform-thread factories. On Java
+ * 21+, the multi-release JAR overlay replaces this class with one that returns
+ * virtual-thread factories, giving the SDK lightweight threads for its
+ * I/O-bound JSON-RPC communication without any user configuration.
+ *
+ * The {@link java.util.concurrent.ScheduledExecutorService} used for
+ * {@code sendAndWait} timeouts in {@link CopilotSession} is not
+ * affected, because the JDK offers no virtual-thread-based scheduled executor.
+ *
+ * @since 0.2.2-java.1
+ */
+final class ThreadFactoryProvider {
+
+ private static final Logger LOG = Logger.getLogger(ThreadFactoryProvider.class.getName());
+
+ private ThreadFactoryProvider() {
+ }
+
+ /**
+ * Creates a new daemon thread with the given name and runnable.
+ *
+ * @param runnable
+ * the task to run
+ * @param name
+ * the thread name for debuggability
+ * @return the new (unstarted) thread
+ */
+ static Thread newThread(Runnable runnable, String name) {
+ Thread t = new Thread(runnable, name);
+ t.setDaemon(true);
+ return t;
+ }
+
+ /**
+ * Creates a single-thread executor suitable for the JSON-RPC reader loop.
+ *
+ * @param name
+ * the thread name for debuggability
+ * @return a single-thread {@link ExecutorService}
+ */
+ static ExecutorService newSingleThreadExecutor(String name) {
+ return Executors.newSingleThreadExecutor(r -> {
+ Thread t = new Thread(r, name);
+ t.setDaemon(true);
+ return t;
+ });
+ }
+
+ /**
+ * Returns {@code true} when this class uses virtual threads (Java 21+
+ * multi-release overlay), {@code false} for platform threads.
+ *
+ * @return whether virtual threads are in use
+ */
+ static boolean isVirtualThreads() {
+ return false;
+ }
+}
diff --git a/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java b/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java
new file mode 100644
index 000000000..0b6720b2d
--- /dev/null
+++ b/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java
@@ -0,0 +1,60 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.logging.Logger;
+
+/**
+ * Java 21+ override that uses virtual threads for the SDK's internal thread
+ * creation.
+ *
+ * This class is placed under {@code META-INF/versions/21/} in the multi-release
+ * JAR and replaces the baseline {@code ThreadFactoryProvider} when running on
+ * Java 21 or later.
+ *
+ * @since 0.2.2-java.1
+ */
+final class ThreadFactoryProvider {
+
+ private static final Logger LOG = Logger.getLogger(ThreadFactoryProvider.class.getName());
+
+ private ThreadFactoryProvider() {
+ }
+
+ /**
+ * Creates a new virtual thread with the given name and runnable.
+ *
+ * @param runnable
+ * the task to run
+ * @param name
+ * the thread name for debuggability
+ * @return the new (unstarted) virtual thread
+ */
+ static Thread newThread(Runnable runnable, String name) {
+ return Thread.ofVirtual().name(name).unstarted(runnable);
+ }
+
+ /**
+ * Creates a virtual-thread-per-task executor for the JSON-RPC reader loop.
+ *
+ * @param name
+ * the thread name prefix for debuggability
+ * @return a virtual-thread {@link ExecutorService}
+ */
+ static ExecutorService newSingleThreadExecutor(String name) {
+ return Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name(name).factory());
+ }
+
+ /**
+ * Returns {@code true} — this is the virtual-thread overlay.
+ *
+ * @return {@code true}
+ */
+ static boolean isVirtualThreads() {
+ return true;
+ }
+}
diff --git a/src/site/markdown/advanced.md b/src/site/markdown/advanced.md
index 5ae5c8f94..19a3d9ae8 100644
--- a/src/site/markdown/advanced.md
+++ b/src/site/markdown/advanced.md
@@ -54,6 +54,7 @@ This guide covers advanced scenarios for extending and customizing your Copilot
- [Session Capabilities](#Session_Capabilities)
- [Outgoing Elicitation via session.getUi()](#Outgoing_Elicitation_via_session.getUi)
- [Getting Session Metadata by ID](#Getting_Session_Metadata_by_ID)
+- [Virtual Threads (Java 21+)](#Virtual_Threads_Java_21)
---
@@ -1237,6 +1238,37 @@ This is more efficient than `listSessions()` when you already know the session I
---
+## Virtual Threads (Java 21+)
+
+When running on **Java 21 or later**, the SDK automatically uses [virtual threads (JEP 444)](https://openjdk.org/jeps/444) for its internal I/O threads. This is implemented via a [Multi-Release JAR (JEP 238)](https://openjdk.org/jeps/238) — no configuration or code changes are required.
+
+### What Uses Virtual Threads
+
+| Component | Thread name | Java 17–20 | Java 21+ |
+|-----------|------------|-------------|----------|
+| JSON-RPC reader loop | `jsonrpc-reader` | Platform (daemon) | Virtual |
+| CLI stderr forwarding | `cli-stderr-reader` | Platform (daemon) | Virtual |
+| `sendAndWait` timeouts | `sendAndWait-timeout` | Platform (daemon) | Platform (daemon) |
+
+The `sendAndWait` timeout scheduler always uses platform threads because the JDK does not provide a virtual-thread-based `ScheduledExecutorService`.
+
+### Performance Implications
+
+Virtual threads are lightweight and scheduled by the JVM on a shared `ForkJoinPool` carrier pool. For the I/O-bound JSON-RPC communication this SDK performs, virtual threads reduce memory footprint and improve scalability when many concurrent sessions are active.
+
+### How It Works
+
+The SDK JAR includes `Multi-Release: true` in its manifest. On Java 21+, the JVM loads the `ThreadFactoryProvider` class from `META-INF/versions/21/`, which uses `Thread.ofVirtual()`. On earlier JVMs, the baseline class under the main class path is loaded, which creates standard platform threads.
+
+### Verifying Virtual Thread Usage
+
+You can check at runtime whether the SDK is using virtual threads:
+
+```java
+// Thread names are preserved for debuggability regardless of thread type.
+// On Java 21+, the jsonrpc-reader and cli-stderr-reader threads will be virtual.
+```
+
## Next Steps
- 📖 **[Documentation](documentation.html)** - Core concepts, events, streaming, models, tool filtering, reasoning effort
diff --git a/src/site/markdown/getting-started.md b/src/site/markdown/getting-started.md
index 39bf43844..913ae7ad2 100644
--- a/src/site/markdown/getting-started.md
+++ b/src/site/markdown/getting-started.md
@@ -18,7 +18,7 @@ Copilot: In Tokyo it's 75°F and sunny. Great day to be outside!
Before you begin, make sure you have:
-- **Java 17+** installed
+- **Java 17+** installed (**Java 21+ recommended** for automatic [virtual thread](https://openjdk.org/jeps/444) support)
- **GitHub Copilot CLI** installed and authenticated ([Installation guide](https://docs.github.com/en/copilot/how-tos/set-up/install-copilot-cli))
Verify the CLI is working:
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
index b599484d9..1abd0efc1 100644
--- a/src/site/markdown/index.md
+++ b/src/site/markdown/index.md
@@ -8,7 +8,7 @@ Welcome to the documentation for the **GitHub Copilot SDK for Java** — a Java
### Requirements
-- Java 17 or later
+- Java 17 or later (**Java 21+ recommended** for automatic [virtual thread](https://openjdk.org/jeps/444) support)
- GitHub Copilot CLI 1.0.17 or later installed and in PATH (or provide custom `cliPath`)
### Installation
diff --git a/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java b/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java
new file mode 100644
index 000000000..a4dcd74f2
--- /dev/null
+++ b/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java
@@ -0,0 +1,62 @@
+/*---------------------------------------------------------------------------------------------
+ * Copyright (c) Microsoft Corporation. All rights reserved.
+ *--------------------------------------------------------------------------------------------*/
+
+package com.github.copilot.sdk;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.junit.jupiter.api.Test;
+
+/**
+ * Tests for {@link ThreadFactoryProvider}, verifying that the factory methods
+ * produce working threads and executors regardless of the Java version.
+ */
+class ThreadFactoryProviderTest {
+
+ @Test
+ void newThreadCreatesNamedThread() {
+ var ran = new AtomicReference();
+ Thread t = ThreadFactoryProvider.newThread(() -> ran.set(Thread.currentThread().getName()), "test-thread");
+ assertNotNull(t);
+ assertEquals("test-thread", t.getName());
+ t.start();
+ try {
+ t.join(5000);
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
+ assertEquals("test-thread", ran.get());
+ }
+
+ @Test
+ void newSingleThreadExecutorRunsTask() throws Exception {
+ ExecutorService executor = ThreadFactoryProvider.newSingleThreadExecutor("test-executor");
+ try {
+ var ran = new AtomicReference(false);
+ executor.submit(() -> ran.set(true)).get(5, TimeUnit.SECONDS);
+ assertTrue(ran.get());
+ } finally {
+ executor.shutdownNow();
+ }
+ }
+
+ @Test
+ void isVirtualThreadsReturnsBoolean() {
+ // On Java 17 this returns false; on Java 21+ it returns true.
+ // We just verify it doesn't throw.
+ boolean result = ThreadFactoryProvider.isVirtualThreads();
+ int javaVersion = Runtime.version().feature();
+ if (javaVersion >= 21) {
+ assertTrue(result, "Expected virtual threads on Java 21+");
+ } else {
+ assertTrue(!result, "Expected platform threads on Java < 21");
+ }
+ }
+}
From ce4fd3d7b0983cce5a6a5af1b85c899703ffa081 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 7 Apr 2026 14:04:27 +0000
Subject: [PATCH 3/7] Address code review feedback: use assertFalse, simplify
README
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/e74714e4-bb84-4af7-b1ef-44f576c5b37c
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
---
README.md | 12 +++---------
.../copilot/sdk/ThreadFactoryProviderTest.java | 3 ++-
2 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/README.md b/README.md
index 63edf0001..dc1de5d28 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ Java SDK for programmatic control of GitHub Copilot CLI, enabling you to build A
### Requirements
-- Java 17 or later. **JDK 21+ recommended** for automatic virtual thread support (see [Virtual Threads](#virtual-threads) below). Selecting JDK 25 additionally enables the use of virtual threads for the custom executor, as shown in the [Quick Start](#quick-start).
+- Java 17 or later. **JDK 21+ recommended** — the SDK automatically uses virtual threads for its internal I/O on Java 21+ (see [Virtual Threads](#virtual-threads)).
- GitHub Copilot CLI 1.0.17 or later installed and in `PATH` (or provide custom `cliPath`)
### Maven
@@ -69,23 +69,17 @@ implementation 'com.github:copilot-sdk-java:0.2.1-java.1'
import com.github.copilot.sdk.CopilotClient;
import com.github.copilot.sdk.events.AssistantMessageEvent;
import com.github.copilot.sdk.events.SessionUsageInfoEvent;
-import com.github.copilot.sdk.json.CopilotClientOptions;
import com.github.copilot.sdk.json.MessageOptions;
import com.github.copilot.sdk.json.PermissionHandler;
import com.github.copilot.sdk.json.SessionConfig;
-import java.util.concurrent.Executors;
-
public class CopilotSDK {
public static void main(String[] args) throws Exception {
var lastMessage = new String[]{null};
// Create and start client
- try (var client = new CopilotClient()) { // JDK 25+: comment out this line
- // JDK 25+: uncomment the following 3 lines for virtual thread support
- // var options = new CopilotClientOptions()
- // .setExecutor(Executors.newVirtualThreadPerTaskExecutor());
- // try (var client = new CopilotClient(options)) {
+ // On Java 21+, the SDK automatically uses virtual threads for internal I/O.
+ try (var client = new CopilotClient()) {
client.start().get();
// Create a session
diff --git a/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java b/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java
index a4dcd74f2..a87782b4e 100644
--- a/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java
+++ b/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java
@@ -5,6 +5,7 @@
package com.github.copilot.sdk;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -56,7 +57,7 @@ void isVirtualThreadsReturnsBoolean() {
if (javaVersion >= 21) {
assertTrue(result, "Expected virtual threads on Java 21+");
} else {
- assertTrue(!result, "Expected platform threads on Java < 21");
+ assertFalse(result, "Expected platform threads on Java < 21");
}
}
}
From af2540dedc1af111f2538e137414cd28169f3416 Mon Sep 17 00:00:00 2001
From: Bruno Borges
Date: Tue, 7 Apr 2026 10:07:58 -0400
Subject: [PATCH 4/7] Update README.md
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
README.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/README.md b/README.md
index dc1de5d28..65e1bf6c3 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ Java SDK for programmatic control of GitHub Copilot CLI, enabling you to build A
### Requirements
-- Java 17 or later. **JDK 21+ recommended** — the SDK automatically uses virtual threads for its internal I/O on Java 21+ (see [Virtual Threads](#virtual-threads)).
+- Java 17 or later. **JDK 21+ recommended** — the SDK automatically uses virtual threads for its internal I/O on Java 21+, and any virtual-thread-based custom executor examples using `Executors.newVirtualThreadPerTaskExecutor()` also require Java 21+ (see [Virtual Threads](#virtual-threads)).
- GitHub Copilot CLI 1.0.17 or later installed and in `PATH` (or provide custom `cliPath`)
### Maven
From 25829a48aad37ede0a7aa4c19a279f2d08a195cf Mon Sep 17 00:00:00 2001
From: Bruno Borges
Date: Tue, 7 Apr 2026 10:08:45 -0400
Subject: [PATCH 5/7] Update
src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../copilot/sdk/ThreadFactoryProviderTest.java | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java b/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java
index a87782b4e..3ea57ce96 100644
--- a/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java
+++ b/src/test/java/com/github/copilot/sdk/ThreadFactoryProviderTest.java
@@ -50,14 +50,16 @@ void newSingleThreadExecutorRunsTask() throws Exception {
@Test
void isVirtualThreadsReturnsBoolean() {
- // On Java 17 this returns false; on Java 21+ it returns true.
- // We just verify it doesn't throw.
+ // Unit tests run against exploded classes rather than the packaged
+ // multi-release JAR, so Java 21+ may still load the base implementation
+ // and report false here. Verify only behavior that does not depend on
+ // multi-release class selection.
boolean result = ThreadFactoryProvider.isVirtualThreads();
int javaVersion = Runtime.version().feature();
- if (javaVersion >= 21) {
- assertTrue(result, "Expected virtual threads on Java 21+");
- } else {
+ if (javaVersion < 21) {
assertFalse(result, "Expected platform threads on Java < 21");
+ } else if (result) {
+ assertTrue(javaVersion >= 21, "Virtual threads are only supported on Java 21+");
}
}
}
From fef1833066f230c874ba235fb785d6f50829df13 Mon Sep 17 00:00:00 2001
From: Bruno Borges
Date: Tue, 7 Apr 2026 10:09:34 -0400
Subject: [PATCH 6/7] s
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
---
.../com/github/copilot/sdk/ThreadFactoryProvider.java | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java b/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java
index 0b6720b2d..72970df70 100644
--- a/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java
+++ b/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java
@@ -39,14 +39,15 @@ static Thread newThread(Runnable runnable, String name) {
}
/**
- * Creates a virtual-thread-per-task executor for the JSON-RPC reader loop.
+ * Creates a single-thread executor backed by a virtual-thread factory for the
+ * JSON-RPC reader loop.
*
* @param name
- * the thread name prefix for debuggability
- * @return a virtual-thread {@link ExecutorService}
+ * the thread name for debuggability
+ * @return a single-thread virtual-thread-backed {@link ExecutorService}
*/
static ExecutorService newSingleThreadExecutor(String name) {
- return Executors.newThreadPerTaskExecutor(Thread.ofVirtual().name(name).factory());
+ return Executors.newSingleThreadExecutor(Thread.ofVirtual().name(name).factory());
}
/**
From 9d456f6c69bd719b56ab17818bdd3f603ea0c9a1 Mon Sep 17 00:00:00 2001
From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com>
Date: Tue, 7 Apr 2026 14:11:59 +0000
Subject: [PATCH 7/7] Remove unused LOG fields, use newSingleThreadExecutor for
Java 21 overlay, fix empty docs section
Agent-Logs-Url: https://github.com/github/copilot-sdk-java/sessions/46706dd3-402c-41c9-9150-3cfae7db8c3f
Co-authored-by: brunoborges <129743+brunoborges@users.noreply.github.com>
---
.../java/com/github/copilot/sdk/ThreadFactoryProvider.java | 3 ---
.../com/github/copilot/sdk/ThreadFactoryProvider.java | 3 ---
src/site/markdown/advanced.md | 7 +------
3 files changed, 1 insertion(+), 12 deletions(-)
diff --git a/src/main/java/com/github/copilot/sdk/ThreadFactoryProvider.java b/src/main/java/com/github/copilot/sdk/ThreadFactoryProvider.java
index 3f8ead92b..2f864d921 100644
--- a/src/main/java/com/github/copilot/sdk/ThreadFactoryProvider.java
+++ b/src/main/java/com/github/copilot/sdk/ThreadFactoryProvider.java
@@ -6,7 +6,6 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.logging.Logger;
/**
* Provides thread factories for the SDK's internal thread creation.
@@ -24,8 +23,6 @@
*/
final class ThreadFactoryProvider {
- private static final Logger LOG = Logger.getLogger(ThreadFactoryProvider.class.getName());
-
private ThreadFactoryProvider() {
}
diff --git a/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java b/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java
index 72970df70..6fef02aca 100644
--- a/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java
+++ b/src/main/java21/com/github/copilot/sdk/ThreadFactoryProvider.java
@@ -6,7 +6,6 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
-import java.util.logging.Logger;
/**
* Java 21+ override that uses virtual threads for the SDK's internal thread
@@ -20,8 +19,6 @@
*/
final class ThreadFactoryProvider {
- private static final Logger LOG = Logger.getLogger(ThreadFactoryProvider.class.getName());
-
private ThreadFactoryProvider() {
}
diff --git a/src/site/markdown/advanced.md b/src/site/markdown/advanced.md
index 19a3d9ae8..9b1484750 100644
--- a/src/site/markdown/advanced.md
+++ b/src/site/markdown/advanced.md
@@ -1262,12 +1262,7 @@ The SDK JAR includes `Multi-Release: true` in its manifest. On Java 21+, the JVM
### Verifying Virtual Thread Usage
-You can check at runtime whether the SDK is using virtual threads:
-
-```java
-// Thread names are preserved for debuggability regardless of thread type.
-// On Java 21+, the jsonrpc-reader and cli-stderr-reader threads will be virtual.
-```
+Thread names are preserved for debuggability regardless of thread type. On Java 21+, a thread dump will show `jsonrpc-reader` and `cli-stderr-reader` as virtual threads rather than platform threads. You can verify this via `jcmd Thread.dump_to_file -format=json ` or your IDE's thread inspector.
## Next Steps