Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

ComplitableFuture doesn't work if it saved to varible

Why if I save future to variable before configuration steps it doesn’t work?

@Test
void simple() {
    CompletableFuture<String> future = CompletableFuture.supplyAsync(this::throwException)
            .exceptionally(throwable -> HANDLED);
    assertEquals(HANDLED, future.join());
}

@Test
void withVar() {
    CompletableFuture<String> future = CompletableFuture.supplyAsync(this::throwException);
    future.exceptionally(throwable -> HANDLED);
    assertEquals(HANDLED, future.join());
}

private String throwException() {
    if (true) {
        throw new RuntimeException(FAIL);
    }
    return SUCCESS;
}

simple() is fine, but withVar() doesn’t work

java.util.concurrent.CompletionException: java.lang.RuntimeException: FAIL

at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:314)
at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:319)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1702)
at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1692)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)`
Caused by: java.lang.RuntimeException: FAIL
    at ru.dionisis.resttest.ComplitableFutureTest.throwException(ComplitableFutureTest.java:35)
    at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1700)
    ... 6 more`

A similar problem was with RestTemplateBulder, when I wanted make otional init one field

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

From the JavaDoc for exceptionally: "Returns a new CompletableFuture…". It does not mutate the CompleteableFuture that it’s called upon.

You are creating a new CompleteableFuture with new behaviour and then throwing that away, then joining on the original CompleteableFuture which does not have that behaviour.

It’s like saying that String::toUpperCase doesn’t work in this example. It does work, but the result is thrown away.

String foo = "bar";
foo.toUpperCase();
assertEquals("BAR", foo);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading