CyberSource / cybersource-rest-client-java

Java client library for the CyberSource REST API
Other
19 stars 42 forks source link

ApiClient.java leaks ResponseBody objects #21

Open tonyrozga opened 5 years ago

tonyrozga commented 5 years ago

hello, if you don't call ResponseBody.close() on your ResponseBody objects you are leaking resources. I've just spent time in the debugger tracing a few runs of the sample DownloadReport.java from your samples repository. ApiClient is clearly not closing the ResponseBody. The only call to close() appears in ApiClient.handleResponse..and it is conditional: only runs if the HTTP status code is 204 (no content ironically). There is a reason ResponseBody implements Closeable. Sorry but no time to contribute code.

gnongsie commented 5 years ago

Hi,

Thank you for bringing this to our attention.

This issue has been addressed in the latest version of the SDK. Kindly fetch the SDK from Maven (v0.0.12) and check again.

Suryakanta26 commented 3 years ago

Hi @gnongsie,

I saw ApiClient.java (in both v0.0.35 & v0.0.36-SNAPSHOT). This issue is still remain. You are only closing ResponseBody object inside handleResponse(Response response, Type returnType) when the response is successful & response status code is 204. But, you should close it every time when the call is successful. This is causing sufficient amount of memory leak.

Here is the reference.

Thanks

Suryakanta26 commented 3 years ago

Hi @gnongsie , Based on your above comment, I have checked codebase of v0.012. Yes I can see two instances of response.body().close();, one inside handleResponse() method another one in execute() method. But the last one got removed in v.0.0.15. Here is the diff.

So, possible solution will be:

Add a private method in ApiClient.java i.e. private void clearResponseBody(Response response){ if (response.body() != null) { response.body().close(); } }

And call it from both execute() & executeAsync() methods. If you do so, you have to remove response.body().close(); logic for response.code() == 204 from handleResponse() method.

I hope this fix will be released asap, as lot's of organization started using Cybersource rest client for their payment needs and are in a spot of bother for this memory leak issue.

Cheers.

Suryakanta26 commented 3 years ago

Hi,

Thank you for for providing response.body().close() in execute() method in v0.0.36 . But the fix is half done, as executeAsync() method still needs the fix.

Thanks

ZipeiXiao commented 2 years ago

Hi team! I am facing the same java.lang.OutOfMemoryError when using cybersource-rest-client-java@0.0.39

WARN  2022-01-07 23:24:26,870  [OkHttp ConnectionPool] okhttp3.OkHttpClient: A connection to https://apitest.cybersource.com/ was leaked. Did you forget to close a response body? To see where this was allocated, set the OkHttpClient logger level to FINE: Logger.getLogger(OkHttpClient.class.getName()).setLevel(Level.FINE);

image