Apache HttpClient Interim Error: NoHttpResponseException

Em Ae picture Em Ae · May 11, 2012 · Viewed 125.3k times · Source

I have a webservice which is accepting a POST method with XML. It is working fine then at some random occasion, it fails to communicate to the server throwing IOException with message The target server failed to respond. The subsequent calls work fine.

It happens mostly, when i make some calls and then leave my application idle for like 10-15 min. the first call which I make after that returns this error.

I tried couple of things ...

I setup the retry handler like

HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {

            public boolean retryRequest(IOException e, int retryCount, HttpContext httpCtx) {
                if (retryCount >= 3){
                    Logger.warn(CALLER, "Maximum tries reached, exception would be thrown to outer block");
                    return false;
                }
                if (e instanceof org.apache.http.NoHttpResponseException){
                    Logger.warn(CALLER, "No response from server on "+retryCount+" call");
                    return true;
                }
                return false;
            }
        };

        httpPost.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, retryHandler);

but this retry never got called. (yes I am using right instanceof clause). While debugging this class never being called.

I even tried setting up HttpProtocolParams.setUseExpectContinue(httpClient.getParams(), false); but no use. Can someone suggest what I can do now?

IMPORTANT Besides figuring out why I am getting the exception, one of the important concerns I have is why isn't the retryhandler working here?

Answer

ok2c picture ok2c · May 15, 2012

Most likely persistent connections that are kept alive by the connection manager become stale. That is, the target server shuts down the connection on its end without HttpClient being able to react to that event, while the connection is being idle, thus rendering the connection half-closed or 'stale'. Usually this is not a problem. HttpClient employs several techniques to verify connection validity upon its lease from the pool. Even if the stale connection check is disabled and a stale connection is used to transmit a request message the request execution usually fails in the write operation with SocketException and gets automatically retried. However under some circumstances the write operation can terminate without an exception and the subsequent read operation returns -1 (end of stream). In this case HttpClient has no other choice but to assume the request succeeded but the server failed to respond most likely due to an unexpected error on the server side.

The simplest way to remedy the situation is to evict expired connections and connections that have been idle longer than, say, 1 minute from the pool after a period of inactivity. For details please see this section of the HttpClient tutorial.