Counter-intuitive behavior of CompleteableFuture

Michał Górniewski via Concurrency-interest <[email protected]> Thu, 20 May 2021 14:28:52 +0200
Newsgroups gmane.comp.java.jsr.166-concurrency
Message-ID <CAMFpyQJ3gxi1uP+unCMS2ETcFF0oQ0C5L_gFLnbJkqoe7Q+iow@mail.gmail.com>
With following code:

------------------------------
public static void main(String[] args) {
    CompletableFuture<String> initial = new CompletableFuture<>();

    CompletableFuture<String> withSteps = initial
            .thenApply(s -> {
                System.out.println("STEP1: " + s);
                return s;
            })
            .thenApply(s -> {
                System.out.println("STEP2: " + s);
                return s;
            });

    CompletableFuture<String> timeout = withSteps;

    timeout.whenComplete((s, throwable) ->
System.out.println("TIMEOUT: " + throwable));

    timeout.completeExceptionally(new RuntimeException("TIMEOUT"));
    initial.complete("SUCCESS");
}
------------------------------

I got output like this:

------------------------------
TIMEOUT: java.lang.RuntimeException: TIMEOUT
STEP1: SUCCESS
------------------------------

I don't understand why "STEP2" is not executed in this case. Is this expected?
For me this API is confusing and may create issues like this:
https://github.com/resilience4j/resilience4j/issues/1427

Thanks,
Michał Górniewski
_______________________________________________
Concurrency-interest mailing list
[email protected]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest