Skip to content

CompletionStage<T>.await() is broken for MinimalStage #2456

Closed
@m50d

Description

@m50d

Many JDK methods that return CompletionStage are internally implemented using a class called MinimalStage, which inherits implementation from CompletableFuture (and therefore extends Future at runtime) but throws UnsupportedOperationException at runtime for most Future methods e.g. isDone(). Provided the caller uses the declared return type of CompletionStage this doesn't matter.
Unfortunately CompletionStage<T>.await() checks reflectively whether the passed CompletionStage implements Future and then calls Future#isDone() if it does, leading to an exception like:

java.lang.UnsupportedOperationException
	at java.base/java.util.concurrent.CompletableFuture$MinimalStage.isDone(CompletableFuture.java:2844)
	at kotlinx.coroutines.future.FutureKt.await(Future.kt:150)

Minimal reproduction (tested on JDK11):

import java.util.concurrent.CompletableFuture
import kotlinx.coroutines.future.await

suspend fun main() {
    CompletableFuture.completedStage(Unit).await()
    println("Hello World") // never called
}

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions