== What each @Async return type hands back ==

completableFuture().get()  : task-5 (virtual=false)
plainString()              : java.lang.IllegalArgumentException: Invalid return type for async method (only Future and void supported): class java.lang.String
futureThatThrows().get()   : IllegalStateException: thrown from a CompletableFuture @Async method
voidThatThrows()           : returned normally. The exception went to
                             SimpleAsyncUncaughtExceptionHandler, which logs it at
                             ERROR under the logger
                             o.s.a.i.SimpleAsyncUncaughtExceptionHandler and
                             discards it. The caller is never told.

