Markus Heiden created CXF-9257:
----------------------------------

             Summary: Client futures never complete if the async callback throws
                 Key: CXF-9257
                 URL: https://issues.apache.org/jira/browse/CXF-9257
             Project: CXF
          Issue Type: Bug
          Components: JAX-RS, JAX-WS Runtime
            Reporter: Markus Heiden


If the callback passed to an asynchronous client invocation throws an unchecked 
exception, the future returned by the invocation is never completed. Threads 
blocked in {{Future.get()}} hang forever, and {{get(timeout)}} is the only way 
out.

*Affected*

* JAX-RS client: {{JaxrsClientCallback}} invokes 
{{InvocationCallback.completed()}} / {{failed()}} before completing its 
{{CompletableFuture}}. An exception thrown by the callback propagates out of 
{{handleResponse()}} / {{handleException()}}, so the future is never completed. 
For {{WebClient}} the call to {{handleResponse()}} in 
{{ClientAsyncResponseInterceptor}} is not even inside a try block, so nothing 
downstream can recover. The same applies to {{cancel()}} and to the 
interruption path of {{JaxrsResponseFuture.get()}}, which both invoke 
{{failed()}}.
* JAX-WS client: {{JaxwsClientCallback}} invokes 
{{AsyncHandler.handleResponse()}} the same way. In addition, when the exception 
escapes, {{ClientImpl}} catches it and calls {{handleException()}}, which 
invokes the same {{AsyncHandler}} a second time and may throw again.

*Expected behaviour*

The future completes in every case. If the callback throws while handling a 
successful response, the future completes exceptionally with that exception, 
which is what the JAX-WS reference implementation does 
({{com.sun.xml.ws.client.AsyncResponseImpl.set}}). If the callback throws while 
handling a failure, the original failure is kept as the cause and the 
callback's exception is attached as a suppressed exception.

*Context*

Observed in the Microsoft Advertising Java SDK, which builds its own futures on 
top of the CXF async client: a runtime exception in its handler, e.g. from a 
missing response header, left the SDK's future unresolved forever. See 
https://github.com/BingAds/BingAds-Java-SDK/issues/166#issuecomment-2016613395 
and https://github.com/BingAds/BingAds-Java-SDK/issues/242.

*Fix*

https://github.com/apache/cxf/pull/3565 guards every callback invocation in 
both callbacks and adds unit tests, which fail without the fix.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to