Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8068432

Inconsistent exception handling in CompletableFuture.thenCompose

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 9
    • 8, 8u25, 9
    • core-libs

        FULL PRODUCT VERSION :
        java version "1.8.0_25"
        Java(TM) SE Runtime Environment (build 1.8.0_25-b17)
        Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)


        ADDITIONAL OS VERSION INFORMATION :
        Linux 3.13.0-37-generic #64-Ubuntu SMP Mon Sep 22 21:28:38 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux

        A DESCRIPTION OF THE PROBLEM :
        CompletableFuture.thenCompose inconsistently handles exception thrown from the CompletionStage created by function. See the steps to reproduce

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        I have this two tests that only differ in order of execution but produce different output.

        @Test
        public void completedAfter() {
            CompletableFuture<String> future1 = new CompletableFuture<>();
            CompletableFuture<String> future2 = new CompletableFuture<>();

            future1.thenCompose(x -> future2).whenComplete((r, e) -> System.out.println("After: " + e));

            future1.complete("value");
            future2.completeExceptionally(new RuntimeException());
        }

        @Test
        public void completedBefore() {
            CompletableFuture<String> future1 = new CompletableFuture<>();
            CompletableFuture<String> future2 = new CompletableFuture<>();

            future1.complete("value");
            future2.completeExceptionally(new RuntimeException());

            future1.thenCompose(x -> future2).whenComplete((r, e) -> System.out.println("Before: " +e));
        }

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        Consistent output, most likely:

        After: java.util.concurrent.CompletionException: java.lang.RuntimeException
        Before: java.util.concurrent.CompletionException: java.lang.RuntimeException

        ACTUAL -
        Inconsistent output:

        After: java.util.concurrent.CompletionException: java.lang.RuntimeException
        Before: java.lang.RuntimeException


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        import org.junit.Test;

        import java.util.concurrent.CompletableFuture;

        public class CompletableFutureComposeTest {

            @Test
            public void completedAfter() {
                CompletableFuture<String> future1 = new CompletableFuture<>();
                CompletableFuture<String> future2 = new CompletableFuture<>();

                future1.thenCompose(x -> future2).whenComplete((r, e) -> System.out.println("After: " + e));

                future1.complete("value");
                future2.completeExceptionally(new RuntimeException());
            }

            @Test
            public void completedBefore() {
                CompletableFuture<String> future1 = new CompletableFuture<>();
                CompletableFuture<String> future2 = new CompletableFuture<>();

                future1.complete("value");
                future2.completeExceptionally(new RuntimeException());

                future1.thenCompose(x -> future2).whenComplete((r, e) -> System.out.println("Before: " +e));
            }
        }
        ---------- END SOURCE ----------

              psandoz Paul Sandoz
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              8 Start watching this issue

                Created:
                Updated:
                Resolved: