A connection to (...) was leaked. Did you forget to close a response body?
Asked Answered
A

2

25

I'm having a warning message constantly, despite my code seems to be good. The message is:

WARNING: A connection to http://someurl.com was leaked. Did you forget to close a response body?
java.lang.Throwable: response.body().close()
    at okhttp3.internal.platform.Platform.getStackTraceForCloseable(Platform.java:148)
    at okhttp3.RealCall.captureCallStackTrace(RealCall.java:89)
    at okhttp3.RealCall.execute(RealCall.java:73)
    at com.example.HTTPSClientReferenceRate.runClient(HTTPSClientReferenceRate.java:78)
    at com.example.HTTPSClientReferenceRate.main(HTTPSClientReferenceRate.java:137)

I'm working with Java 8. I've tried with the traditional try-catch and with this approach (try-with-resources):

boolean repeatRequest = true;

while(repeatRequest) {
    Call call = client.newCall(request);
    try (Response response = call.execute()){
        if (!response.isSuccessful()) {
            log.error("Error with the response: " + response.message());
            continue;
        }
        ResponseBody body = response.body();
        if (body == null){
            log.error("Error when getting body from the response: " + response.message());
            continue;
        }
        BufferedReader br = new BufferedReader(body.charStream());

        //...DATA HANDLING

    } catch (Exception e) {
        log.error("Error Connecting to the stream. Retrying... Error message: " + e.getMessage());
    }
}

In fact, the first if line is never called, I always have an exception, so I cannot understand why the response/body is not closed by the try-with-resources block

I've tried this option as well, but it didn't work either:

try (Response response = client.newCall(request).execute()) { ... }

EDIT

I've reduced my code, and I'm still having the same error, this is even weirder:

boolean repeatRequest = true;

while(repeatRequest) {
    Call call = client.newCall(request);
    try (Response response = call.execute()){
        //NOTHING
    } catch (Exception e) {
        log.error("Error Connecting to the stream. Retrying... Error message: " + e.getMessage());
    }
}

EDIT 2:

I've tried with the traditional try-catch but I'm still having the same issue:

boolean repeatRequest = true;

while(repeatRequest) {
    Call call = client.newCall(request);
    Response response = null;
    try {
        response = call.execute();
        try (ResponseBody body = response.body()) {
            //Nothing...
        }
    } catch (Exception e) {
        log.error("Error Connecting to the stream. Retrying... Error message: " + e.getMessage());
    } finally {
        if (response != null){
            response.close();
        }
    }
}
Augmenter answered 29/7, 2019 at 19:21 Comment(9)
try this : try (Response response = client.newCall(request).execute()) {Arsis
@btreport I've tried that before without luck, I'll add it to my post description.Augmenter
which version of java you working on?Ziegfeld
@ErHarshRathore I'm working with Java 8Augmenter
As per my knowledge java 8 is not able to read this try (Response response = call.execute()){} instead you should try the declaration and definition separately like Response response; try (response = call.execute())Ziegfeld
@ErHarshRathore try-with-resources was added in Java 7, so that's not the issue here.Augmenter
try(Declaration + Definition) {} feature is first introduced in java 9Ziegfeld
@ErHarshRathore maybe you're confused about this, in fact, Response response; try (response = call.execute()) is not valid.Augmenter
@Augmenter yes I am getting little bit confused. SorryZiegfeld
R
15

As per Response.close() javadoc:

It is an error to close a response that is not eligible for a body. This includes the responses returned from cacheResponse, networkResponse, and priorResponse().

Perhaps your code should look like below, as per Github comment:

while (repeatRequest) {
    Call call = client.newCall(request);
    Response response = call.execute();
    try (ResponseBody body = response.body()) {
        ...
    }
}
Roid answered 29/7, 2019 at 19:48 Comment(9)
Karol, I've edited my post, you could see that the error seems to be somewhere else, any ideas?Augmenter
You are closing Response with try-with-resource block. The docs says not to do this for some responses, try the code suggested on Github.Roid
Karol, I've added a new edit to my post, am I missing something? ThanksAugmenter
@Augmenter I have updated the example you have to add exception handling to match your method signature.Roid
I've updated the edit 2, still having the issue. I tried debugging, and the code jumps from response = call.execute(); to the catch block, and the response is always null... despite of that, the error is still happeningAugmenter
@Augmenter what is the version of OkHttp you are using?Roid
I'm using 3.10.0, and I've also tried with 3.14.2 and 4.0.1 without luckAugmenter
I use retrofit, it automatically should close everythingCordula
What happens if you don't close it? Memory leak?Gennagennaro
M
0

When using Kotlin, this can easily be handled by closing the respoonse.body if it is non-null. If a body is present, closing it closes the source but if it is not present, closing is not required. For example:

                    val response = client.newCall(request).execute()
                    // check for response.isSuccessful here, or read the body if required
                    response.body?.close()
Mims answered 26/2, 2022 at 4:10 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.