Java 8 的不同次要版本下 CompletionException 的不同消息

Different messages for CompletionException under different minor versions of Java 8

我在 java 的不同次要版本下从同一代码片段得到不同的输出。我无法在开放的 jdk 错误跟踪器上找到相关票证。

CompletableFuture<String> completableFuture = new CompletableFuture<>();
completableFuture.complete("xxx");

completableFuture.thenCompose(str -> {
    CompletableFuture<String> completableFuture1 = new CompletableFuture<>();
    completableFuture1.completeExceptionally(new Exception("hello"));
    return completableFuture1;
}).exceptionally(ex -> {
    System.out.println(ex.getMessage());
    return null;
}).get();

JDK1.8下的输出。0_25:

hello

JDK1.8下的输出。0_102:

java.lang.Exception: hello

较新的是修复还是回归?相关票是什么?

有错误报告 here discussing this change. The key is in the Javadoc of CompletableFuture#thenCompose

Returns a new CompletionStage that, when this stage completes normally, is executed with this stage as the argument to the supplied function. See the CompletionStage documentation for rules covering exceptional completion.

和 class CompletionStage

的文档

In all other cases, if a stage's computation terminates abruptly with an (unchecked) exception or error, then all dependent stages requiring its completion complete exceptionally as well, with a CompletionException holding the exception as its cause.

这就是您在这里看到的。您传递给 exceptionallyFunction 现在收到一个 CompletionException 持有完成触发 CompletableFuture.

Exception

您现在看到的行为是预期的行为。

您必须解包才能获得异常完成的原因

Throwable cause = ex.getCause(); // this is your Exception("Hello")

这是一个问题,已在 9 中修复并向后移植到 8u60。你会看到java.lang.Exception: hello from 8u60 onwards.