The java implementation seems to lean on trying to pass context objects around implicitly as a ThreadLocal. This will cause pain and suffering in the presence of async, multithreaded code: your trace context will be present in the thread where your request handler began, but won't be present in threads running callbacks from non-blocking IO libraries (netty, akka-http, async-http-client, redisson, etc).
Async style is not incompatible with storing the trace context in thread-local storage. You just capture the trace context when you create the callback. That's how Dapper works, in C++ and Java. See section 2.2 of the Dapper paper. https://storage.googleapis.com/pub-tools-public-publication-...
OpenTelemetry can't guarantee that their users will use a specific library to create callbacks and can't then ensure that this library wraps callbacks with the appropriate threadlocal setup.
Users would by default run into problems unless they take a number of precautionary steps.