Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OkHttp: avoid leaked connection warning

I am using OkHttp 3, and I keep getting leaked connection warnings:

WARNING: A connection to https://help.helpling.com/ was leaked. Did you forget to close a response body? Jul 14, 2016 6:57:09 PM okhttp3.ConnectionPool pruneAndGetAllocationCount 

Everytime I get a ResponseBody, I either call .string() which supposedly closes the stream for me, or I explicitly close it in a finally block, in the following way:

ResponseBody responseBody = response.body(); try (Reader responseReader = responseBody.charStream()) {     ... } finally {     responseBody.close(); } 

My application makes intense use of the network, and yet that warning appears frequently. I never observed any problem caused by this presumed leak, but I would still like to understand if and what I am doing wrong.

Could anyone shed some light on this?

like image 429
Alphaaa Avatar asked Jul 14 '16 17:07

Alphaaa


People also ask

Why did my okhttp network connection fail?

Network failures can be due to client connectivity problems, server availability problems, or anything between. OkHttp supports connect, read, and write timeouts. In this example, we built our client with a readTimeout of 1 seconds, while the URL is served with 2 seconds of delay:

What is HTTP2 okhttp?

2. OkHttp Overview OkHttp is an efficient HTTP & HTTP/2 client for Android and Java applications. It comes with advanced features such as connection pooling (if HTTP/2 isn’t available), transparent GZIP compression, and response caching to avoid the network completely for repeated requests.

How do I make a GET request asynchronous in okhttp?

Asynchronous GET With OkHttp Now, to make an asynchronous GET we need to enqueue a Call. A Callback allows us to read the response when it is readable. This happens after the response headers are ready. Reading the response body may still block. OkHttp doesn't currently offer any asynchronous APIs to receive a response body in parts: 6.

What is okhttp in Android?

OkHttp Overview. OkHttp is an efficient HTTP & HTTP/2 client for Android and Java applications. It comes with advanced features such as connection pooling (if HTTP/2 isn’t available), transparent GZIP compression, and response caching to avoid the network completely for repeated requests.


2 Answers

By upgrading to OkHttp 3.7, Eclipse started warning me of potential resource leaks. I found my problem to be in this method I wrote:

public static Response getResponse(HttpUrl url, OkHttpClient client) throws IOException {     Builder request = new Request.Builder().url(url);     Response response = client.newCall(request.build()).execute();     if (!response.isSuccessful()) {         boolean repeatRequest = handleHttpError(response);         if (repeatRequest)             return getResponse(url, client, etag);         else             throw new IOException(String.format("Cannot get successful response for url %s", url));     }     return response; } 

I assumed that by always calling getResponse(url, client).body().string() the stream would close automatically. But, whenever a response was unsuccessful, an exception would raise before the execution of .string(), thus the stream would remain open.

Adding an explicit close in case of unsuccessful response solved the problem.

if (!response.isSuccessful()) {     boolean repeatRequest = handleHttpError(response);     response.close(); } 
like image 113
Alphaaa Avatar answered Sep 21 '22 00:09

Alphaaa


As mentioned in the other answers, you have to close the response. A slightly cleaner approach would be to declare the ResponseBody in the try block, so that it will be automatically closed.

try(ResponseBody body = ....){ .... } 
like image 38
Corrigan Johnson Avatar answered Sep 19 '22 00:09

Corrigan Johnson