On Sun, 2021-08-22 at 11:32 +0530, Jaikiran Pai wrote:
> While looking into an issue in the Quarkus project, it has been
> observed 
> that the Apache HTTP client library (4.5.13 version) behaves
> differently 
> against Java 11 and Java 16 when it comes to HTTP request retries.
> The 
> initial issue that triggered this investigation is explained here[1].
> 
> As noted in that comment, the Apache HTTP client library has a 
> "RetryExec" which uses a "HttpRequestRetryHandler" implementation to 
> decide whether to retry an request which failed. The default 
> implementation of "HttpRequestRetryHandler" is the 
> "DefaultHttpRequestRetryHandler" which among other things, uses a 
> collection of exception types to decide which requests shouldn't be 
> retried. One such exception type is "java.net.ConnectException" for 
> which request won't be retried.
> 
> What's happening now is that, in Java 11 the call to 
> java.net.Socket.connect(addr, timeout) was leading to a 
> "ConnectException" in certain cases. That same call now throws a 
> "java.net.NoRouteToHostException" starting Java 13+. As a result, a 
> request against the same host/port in Java 11 doesn't trigger a
> request 
> retry (because it throws ConnectException) whereas the same request 
> triggers a retry in Java 16 (because it throws
> NoRouteToHostException).
> 
> The issue of the same Socket.connect(...) API returning different 
> exception types was raised in the OpenJDK mailing list here[2]. As 
> discussed in that mail thread, it's _not_ a bug in the JDK 
> implementation, since it still throws an IOException (which both 
> ConnectException and NoRouteToHostException are) from the 
> Socket.connect(...) call, as per its (javadoc) contract. That mail 
> thread has additional details on the exact case where this behaviour 
> difference is noticed and the reason for it.
> 
> With that context, should the implementation in the Apache HTTP
> client 
> be changed to take care of this inconsistency? Should both 
> ConnectException and NoRouteToHostException be treated the same in
> the 
> retry handling logic?
> 
> To make it easier to test/check this issue, I have a shared a
> reproducer 
> here[3] as a github repo which shows what's going on. It uses Apache 
> HTTP client 4.5.13 and as noted in the README.md, running that
> example 
> with Java 11 and Java 16 will show the inconsistency - the log
> messages 
> will show that the RetryExec will retry the request in Java 16,
> whereas 
> it won't in Java 11:
> 
>  > RetryExec - Retrying request to {}->http://microprofile.io:1234
> 
> [1] https://github.com/quarkusio/quarkus/pull/19559#issue-717104474
> 
> [2] 
> https://mail.openjdk.java.net/pipermail/net-dev/2021-August/016409.html
> 
> [3] https://github.com/jaikiran/httpclient-reproducer
> 
> -Jaikiran
> 
> 

Hi Jaikiran

I am not entirely sure what we can do here. HttpClient 4.x is Java 1.6
compatible and therefore we can use neither Java 11 nor Java 16 API
directly. The easiest way to address the problem is by using a custom
HttpRequestRetryHandler with Java 16 specific logic.

Cheers

Oleg






---------------------------------------------------------------------
To unsubscribe, e-mail: httpclient-users-unsubscr...@hc.apache.org
For additional commands, e-mail: httpclient-users-h...@hc.apache.org

Reply via email to