HttpClient 4.0.1 - how to release connection?

JavaConnectionApache Httpclient-4.x

Java Problem Overview


I have a loop over a bunch of URLs, for each one I'm doing the following:

private String doQuery(String url) {

  HttpGet httpGet = new HttpGet(url);
  setDefaultHeaders(httpGet); // static method
  HttpResponse response = httpClient.execute(httpGet);   // httpClient instantiated in constructor

  int rc = response.getStatusLine().getStatusCode();
	
  if (rc != 200) {
    // some stuff...
    return;
  }
	
  HttpEntity entity = response.getEntity();
	
  if (entity == null) {
    // some stuff...
    return;
  }

  // process the entity, get input stream etc

}

The first query is fine, the second throws this exception:

> Exception in thread "main" > java.lang.IllegalStateException: > Invalid use of > SingleClientConnManager: connection > still allocated. Make sure to release > the connection before allocating > another one. at > org.apache.http.impl.conn.SingleClientConnManager.getConnection(SingleClientConnManager.java:199) > at > org.apache.http.impl.conn.SingleClientConnManager$1.getConnection(SingleClientConnManager.java:173)......

This is just a simple single-threaded app. How can I release this connection?

Java Solutions


Solution 1 - Java

The recommended way, by Httpcomponents 4.1, is to close connection and release any underlying resources:

EntityUtils.consume(HttpEntity)

where HttpEntity passed is a response entity.

Solution 2 - Java

This seems to work great :

      if( response.getEntity() != null ) {
         response.getEntity().consumeContent();
      }//if

And don't forget to consume the entity even if you didn't open its content. For instance, you expect a HTTP_OK status from the response and don't get it, you still have to consume the entity !

Solution 3 - Java

To answer my own question: to release the connection (and any other resources associated with the request) you must close the InputStream returned by the HttpEntity:

InputStream is = entity.getContent();

.... process the input stream ....

is.close();       // releases all resources

From the docs

Solution 4 - Java

Since version 4.2, they introduced a much more convenience method that simplifies connection release: HttpRequestBase.releaseConnection()

Solution 5 - Java

I'm chiming in with a detailed answer that specifically addresses Apache HttpClient 4.0.1. I'm using this HttpClient version, since it's provided by WAS v8.0, and I need to use that provided HttpClient within Apache Wink v1.1.1, also provided by WAS v8.0, to make some NTLM-authenticated REST calls to Sharepoint.

To quote Oleg Kalnichevski on the Apache HttpClient mailing list:

> Pretty much all this code is not necessary. (1) HttpClient will automatically release the underlying connection as long as the entity content is consumed to the end of stream; (2) HttpClient will automatically release the underlying connection on any I/O exception thrown while reading the response content. No special processing is required in such as case.

> In fact, this is perfectly sufficient to ensure proper release of resources: > > > HttpResponse rsp = httpclient.execute(target, req); > HttpEntity entity = rsp.getEntity(); > if (entity != null) { > InputStream instream = entity.getContent(); > try { > // process content > } finally { > instream.close(); > // entity.consumeContent() would also do > } > } > >That is it.

Source

Solution 6 - Java

If the response is not to be consumed, then the request can be aborted using the code below:

// Low level resources should be released before initiating a new request
HttpEntity entity = response.getEntity();
        
if (entity != null) {
    // Do not need the rest
    httpPost.abort();
}

Reference: http://hc.apache.org/httpcomponents-client-ga/tutorial/html/fundamentals.html#d5e143

Apache HttpClient Version: 4.1.3

Solution 7 - Java

I've got this problem when I use HttpClient in Multithread envirnoment (Servlets). One servlet still holds connection and another one want to get connection.

Solution:

version 4.0 use ThreadSafeClientConnManager

version 4.2 use PoolingClientConnectionManager

and set this two setters:

setDefaultMaxPerRoute
setMaxTotal

Solution 8 - Java

I'm using HttpClient 4.5.3, using CloseableHttpResponse#close worked for me.

    CloseableHttpResponse response = client.execute(request);

    try {
        HttpEntity entity = response.getEntity();
        String body = EntityUtils.toString(entity);
        checkResult(body);
        EntityUtils.consume(entity);
    } finally {
        response.close();
    }

With Java7 and beyond:

try (CloseableHttpResponse response = client.execute(request)) {
   ...
}

Solution 9 - Java

HTTP HEAD requests must be treated slightly differently because response.getEntity() is null. Instead, you must capture the HttpContext passed into HttpClient.execute() and retrieve the connection parameter to close it (in HttpComponents 4.1.X anyway).

HttpRequest httpRqst = new HttpHead( uri );
HttpContext httpContext = httpFactory.createContext();
HttpResponse httpResp = httpClient.execute( httpRqst, httpContext );
        
...
        
// Close when finished
HttpEntity entity = httpResp.getEntity();
if( null != entity )
  // Handles standard 'GET' case
  EntityUtils.consume( entity );
else {
  ConnectionReleaseTrigger  conn =
      (ConnectionReleaseTrigger) httpContext.getAttribute( ExecutionContext.HTTP_CONNECTION );
  // Handles 'HEAD' where entity is not returned
  if( null != conn )
    conn.releaseConnection();
}

HttpComponents 4.2.X added a releaseConnection() to HttpRequestBase to make this easier.

Solution 10 - Java

If you want to re-use the connection then you must consume content stream completely after every use as follows :

EntityUtils.consume(response.getEntity())

Note : you need to consume the content stream even if the status code is not 200. Not doing so will raise the following on next use :

Exception in thread "main" java.lang.IllegalStateException: Invalid use of SingleClientConnManager: connection still allocated. Make sure to release the connection before allocating another one.

If it's a one time use, then simply closing the connection will release all the resources associated with it.

Solution 11 - Java

Highly recommend using a handler to handle the response.

client.execute(yourRequest,defaultHanler);

It will release the connection automatically with consume(HTTPENTITY) method.

A handler example:

private ResponseHandler<String> defaultHandler = new ResponseHandler<String>() {
    @Override
    public String handleResponse(HttpResponse response)
        throws IOException {
        int status = response.getStatusLine().getStatusCode();

        if (status >= 200 && status < 300) {
            HttpEntity entity = response.getEntity();
            return entity != null ? EntityUtils.toString(entity) : null;
        } else {
            throw new ClientProtocolException("Unexpected response status: " + status);
        }
    }
};

Solution 12 - Java

I had the same issue and solved it by closing the response at the end of the method:

try {
    // make the request and get the entity 
} catch(final Exception e) {
    // handle the exception
} finally {
    if(response != null) {
        response.close();
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichard HView Question on Stackoverflow
Solution 1 - JavaYaduView Answer on Stackoverflow
Solution 2 - JavaSnicolasView Answer on Stackoverflow
Solution 3 - JavaRichard HView Answer on Stackoverflow
Solution 4 - JavawikierView Answer on Stackoverflow
Solution 5 - JavaChris HarrisView Answer on Stackoverflow
Solution 6 - JavaJignesh GohelView Answer on Stackoverflow
Solution 7 - JavachrisView Answer on Stackoverflow
Solution 8 - JavaFan JinView Answer on Stackoverflow
Solution 9 - JavawbdarbyView Answer on Stackoverflow
Solution 10 - JavaAyman HussainView Answer on Stackoverflow
Solution 11 - JavaLincolnView Answer on Stackoverflow
Solution 12 - JavakerlView Answer on Stackoverflow