Skip to content

Commit e335d5e

Browse files
mikehearnsdelamo
andauthored
Disable Loom support on JVMs that support the virtual threads API but don't really implement it. (#11856)
Disable Loom support on JVMs that support the virtual threads API but don't really implement it. This avoids a crash when a thread is cast to VirtualThread but is in fact a ThreadBuilder.BoundVirtualThread that uses a platform thread instead. Espresso is an example of such a JVM. * remove unused imports --------- Co-authored-by: Sergio del Amo <[email protected]>
1 parent 69fa75e commit e335d5e

File tree

2 files changed

+12
-5
lines changed

2 files changed

+12
-5
lines changed

context/src/main/java/io/micronaut/runtime/context/scope/refresh/RefreshScope.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
import io.micronaut.context.BeanContext;
2020
import io.micronaut.context.BeanRegistration;
2121
import io.micronaut.context.LifeCycle;
22-
import io.micronaut.context.annotation.ConfigurationProperties;
2322
import io.micronaut.context.annotation.ConfigurationReader;
2423
import io.micronaut.context.annotation.Requires;
2524
import io.micronaut.context.event.ApplicationEventListener;

context/src/main/java/io/micronaut/scheduling/LoomSupport.java

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,18 @@ public final class LoomSupport {
7171
isVirtual = MethodHandles.lookup()
7272
.findVirtual(Thread.class, "isVirtual", MethodType.methodType(boolean.class));
7373

74-
// invoke, this will throw an UnsupportedOperationException if we don't have --enable-preview
75-
ofVirtual.invoke();
76-
77-
sup = true;
74+
// This will throw if this Java doesn't support Loom, or if it does but only with
75+
// --enable-preview.
76+
Thread probe = (Thread) unstarted.invoke(ofVirtual.invoke(), (Runnable) () -> { });
77+
78+
// This checks if the JVM actually creates real virtual threads, or if it uses
79+
// 'bound threads' which are just platform threads. As of June 2025 the Espresso JVM
80+
// falls into this category. Checking here voids casting issues later in code that
81+
// makes assumptions about the internals.
82+
sup = Class.forName("java.lang.VirtualThread").isInstance(probe);
83+
if (!sup) {
84+
failure = new Exception("This JVM doesn't fully implement virtual threads and produces regular platform threads instead.");
85+
}
7886
} catch (Throwable e) {
7987
newThreadPerTaskExecutor = null;
8088
ofVirtual = null;

0 commit comments

Comments
 (0)