It's not clear must I close JAX RS Client/Response instances or not. And if I must, always or not?
According to documentation about the Client class:
Calling this method effectively invalidates all resource targets produced by the client instance.
The WebTarget class does not have any invalidate()/close() method, but the Response class does. According to documentation:
Close the underlying message entity input stream (if available and open) as well as releases any other resources associated with the response (e.g. buffered message entity data).
... The close() method should be invoked on all instances that contain an un-consumed entity input stream to ensure the resources associated with the instance are properly cleaned-up and prevent potential memory leaks. This is typical for client-side scenarios where application layer code processes only the response headers and ignores the response entity.
The last paragraph is not clear to me. What does "un-consumed entity input stream" mean? If I get an InputSteam or a String from response, should I close the response explicitly?
We can get a response result without getting access to Response instance:
Client client = ...;
WebTarget webTarget = ...;
Invocation.Builder builder = webTarget.request(MediaType.APPLICATION_JSON_TYPE);
Invocation invocation = builder.buildGet();
InputStream reso = invocation.invoke(InputStream.class);
I'm working with RESTeasy implementation, and I expected that response will be closed inside of resteasy implementation, but I could not find it. Could anyone tell me why? I know that the Response class will implement Closeable interface But even know, the Response is used, without closing it.
In short: do call close() or use closeable with try-with-resources-statements.
Resources/Reference:
According to the Resteasy documentation you should call close() on Response references. In section 47.3 at the end it states that
Resteasy will release the connection under the covers. The only counterexample is the case in which the response is an instance of InputStream, which must be closed explicitly.
On the other hand, if the result of an invocation is an instance of Response, then Response.close() method must be used to released the connection.
You should probably execute this in a try/finally block. Again, releasing a connection only makes it available for another use. It does not normally close the socket.
Note that if ApacheHttpClient4Engine has created its own instance of HttpClient, it is not necessary to wait for finalize() to close open sockets. The ClientHttpEngine interface has a close() method for this purpose.
Finally, if your javax.ws.rs.client.Client class has created the engine automatically for you, you should call Client.close() and this will clean up any socket connections.
According to the documentation close()
is idempotent.
This operation is idempotent, i.e. it can be invoked multiple times with the same effect which also means that calling the close() method on an already closed message instance is legal and has no further effect.
So you can safely close the InputStream
yourself and should.
That being said I style wise would not do invocation.invoke(InputStream.class)
as the invoker(Class)
is made for doing entity transformation. Instead if you want InputStream you should probably just call invocation.invoke()
and deal with the Response
object directly as you may want some header info before reading the stream.
The reason you want headers when dealing with a response InputStream
is typical because you either don't care about the body or the body requires special processing and size considerations which is what the documentation is alluding to (e.g. HEAD
request to ping server).
See also link
A message instance returned from this method will be cached for subsequent retrievals via getEntity(). Unless the supplied entity type is an input stream, this method automatically closes the an unconsumed original response entity data stream if open. In case the entity data has been buffered, the buffer will be reset prior consuming the buffered data to enable subsequent invocations of readEntity(...) methods on this response.
So if you choose anything other than InputStream
you will not have to close the Response
(but regardless its safe to do it anyways as its idempotent).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With