Find CompletableFuture async calls without an Executor
MSALFinds CompletableFuture and CompletionStage *Async calls that don't pass an Executor, and CompletableFuture.delayedExecutor calls without a base Executor. These run on ForkJoinPool.commonPool(). Before JDK 25, a common pool with parallelism of 1 or less (e.g. on a 2-CPU host) made CompletableFuture fall back to a new thread per task; from JDK 25 that fallback is gone, so blocking work queues behind a single worker thread. Calls that pass ForkJoinPool.commonPool() explicitly are also found, because they got the same fallback before JDK 25. Review each call and pass a dedicated Executor where the task blocks.
org. openrewrite. java. migrate. search. FindCompletableFutureDefaultExecutormod run . --recipe= org. openrewrite. java. migrate. search. FindCompletableFutureDefaultExecutorInstall it once from Recipe actions, then run it on every repository under the current directory. New to the Moderne CLI? Set it up.