Unsupported Method On Virtual Thread
ID |
java.virtual_thread_unsupported_method |
Severity |
high |
Remediation Complexity |
trivial |
Remediation Risk |
low |
Remediation Effort |
low |
Resource |
Reliability |
Language |
Java |
Tags |
reliability |
Description
Reports a call to setDaemon, setPriority or getThreadGroup on a local variable whose
initializer creates a virtual thread — Thread.ofVirtual()….start(…) /
.unstarted(…), or Thread.startVirtualThread(…).
Virtual-ness is decided only from the local’s own initializer in the same method; a Thread
parameter or field is never assumed virtual. setDaemon(true) is reported alongside
setDaemon(false): it does not throw, but it is redundant, since a virtual thread’s daemon
status can never be anything but true.
Rationale
Three Thread methods behave differently, and worse, on a virtual thread than on a platform
one:
-
setDaemon(false)throwsIllegalArgumentException— a virtual thread’s daemon status is alwaystrueand cannot be changed; -
setPriority(int)silently does nothing — a virtual thread’s priority always staysThread.NORM_PRIORITY; -
getThreadGroup()returns a dummy, empty placeholder group that should not be used for anything.
Thread worker = Thread.ofVirtual().unstarted(() -> process());
worker.setPriority(Thread.MAX_PRIORITY); // silently has no effect
worker.setDaemon(false); // throws IllegalArgumentException
worker.setDaemon(true); // redundant: a virtual thread is always a daemon
ThreadGroup group = worker.getThreadGroup(); // a dummy, empty placeholder group
worker.start();
Remediation
Drop the call entirely for a virtual thread — none of these three properties can be configured on one:
Thread worker = Thread.ofVirtual().unstarted(() -> process());
worker.start();