Skip to content

Fix IllegalStateException in SchedulerToExecutorService.invokeAny#8159

Merged
akarnokd merged 1 commit into
ReactiveX:4.xfrom
vasiliy-mikhailov:fix/scheduler-executor-invokeany-exceptionnow
Jun 22, 2026
Merged

Fix IllegalStateException in SchedulerToExecutorService.invokeAny#8159
akarnokd merged 1 commit into
ReactiveX:4.xfrom
vasiliy-mikhailov:fix/scheduler-executor-invokeany-exceptionnow

Conversation

@vasiliy-mikhailov

Copy link
Copy Markdown
Contributor

Problem

SchedulerToExecutorService.invokeAny() checks each future with:

if (f.isDone() && !f.isCancelled() && f.exceptionNow() == null) {

But Future.exceptionNow() is specified to throw IllegalStateException when the task completed normally (there is no exception to return). So as soon as a task finishes successfully, this guard calls exceptionNow() on a successfully-completed future and throws IllegalStateException instead of returning the result. Both invokeAny overloads contain the same probe.

Fix

Use the intended state query, which never throws:

if (f.state() == Future.State.SUCCESS) {

Test

Adds SchedulerToExecutorServiceTest covering the success paths. The new invokeAnyShouldReturnResultOfCompletedTask and invokeAnyWithSingleTask tests fail on master with IllegalStateException and pass with this fix.

Note: the timed invokeAny(tasks, timeout, unit) overload has a separate pre-existing issue in its time accounting (the FIXME-marked spin loop) that this PR intentionally does not touch; it only addresses the exceptionNow() misuse.

invokeAny() guarded its result check with f.exceptionNow() == null, but
Future.exceptionNow() throws IllegalStateException when the task completed
normally (i.e. there is no exception), per its contract. As a result the
first successfully completed task triggers an IllegalStateException instead
of being returned. Both invokeAny overloads are affected.

Replace the isDone/isCancelled/exceptionNow probe with a direct
Future.State.SUCCESS check, which is the intended state query and does not
throw.
@github-actions

Copy link
Copy Markdown

🐷 TruffleHog + Entropy Beauty Scan

Average entropy of changed code: 4.708 bits/char
Verdict: ⚠️ Consider review — entropy outside sweet spot

Changed files entropy:

src/jmh/java/io/reactivex/rxjava4/core/EachTypeFlatMapPerf.java: 5.037
src/jmh/java/io/reactivex/rxjava4/core/FlatMapJustPerf.java: 5.157
src/jmh/java/io/reactivex/rxjava4/core/TakeUntilPerf.java: 4.969
src/jmh/java/io/reactivex/rxjava4/xmapz/FlowableConcatMapMaybePerf.java: 5.134
src/jmh/java/io/reactivex/rxjava4/xmapz/FlowableConcatMapSinglePerf.java: 5.129
src/jmh/java/io/reactivex/rxjava4/xmapz/FlowableFlatMapMaybePerf.java: 5.138
src/jmh/java/io/reactivex/rxjava4/xmapz/FlowableFlatMapSinglePerf.java: 5.131
src/jmh/java/io/reactivex/rxjava4/xmapz/FlowableSwitchMapMaybePerf.java: 5.139
src/jmh/java/io/reactivex/rxjava4/xmapz/FlowableSwitchMapSinglePerf.java: 5.133
src/main/java/io/reactivex/rxjava4/core/Streamable.java: 4.517
src/main/java/io/reactivex/rxjava4/schedulers/Schedulers.java: 4.729
src/test/java/io/reactivex/rxjava4/completable/CompletableIsolatedTest.java: 4.791
src/test/java/io/reactivex/rxjava4/completable/CompletableTest.java: 4.620
src/test/java/io/reactivex/rxjava4/completable/CompletableTimerTest.java: 4.973
src/test/java/io/reactivex/rxjava4/core/XFlatMapTest.java: 4.346
src/test/java/io/reactivex/rxjava4/disposables/CompositeDisposableTest.java: 4.498
src/test/java/io/reactivex/rxjava4/disposables/DisposableTest.java: 4.653
src/test/java/io/reactivex/rxjava4/flowable/FlowableBackpressureTests.java: 4.593
src/test/java/io/reactivex/rxjava4/flowable/FlowableCollectTest.java: 4.598
src/test/java/io/reactivex/rxjava4/flowable/FlowableConversionTest.java: 4.393

✅ No secrets or suspicious high-entropy strings found.

Mid-4 beauty heuristic in action — powered by our entropy chats! 😊

@akarnokd

Copy link
Copy Markdown
Member

Will fix the ParallelScheduler test leak in a separate PR

@akarnokd akarnokd merged commit b901fac into ReactiveX:4.x Jun 22, 2026
2 of 4 checks passed
@akarnokd akarnokd mentioned this pull request Jun 22, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants