0

In our existing codebase, due to the JAX-RX Client API document:

Clients are heavy-weight objects that manage the client-side communication infrastructure. Initialization as well as disposal of a Client instance may be a rather expensive operation. It is therefore advised to construct only a small number of Client instances in the application.

The javax.ws.rs.client.Client was used as a singleton inside the Resource. The code looks like:

@Path("test")
public class TestResource {
    private Client client = ClientUtil.getInstance();//Get the singleton Client instance
    @PUT
    @Produces("application/json")
    public String update(@Context UriInfo uri,
    @Context HttpHeaders headers) {
        ...client is used for sending request to some other service
    }
}

Problem: The TestSource is not used by a single user but multiple users and, each of them uses its own credential, meaning each user has its own configuration. The following method chain is bound to be called in any case:

client.getTarget()
    .request()
    .header(HttpHeaders.AUTHORIZATION, "authorization header value")
    ....

=> concurrency issue

Question 1: Is the javax.ws.rs.client.Client instance in the code thread-safe?**Question 2: If not thread-safe, how to resolve the thread-saftey issue? Should I synchronize this singleton Client instance? or try to make each user have it own Client instance and maintain it in a thread-safe collection? or are there any better alternative solutions?

Rui
  • 3,454
  • 6
  • 37
  • 70
  • As far as you don't modify the client, you are good to go. The issue arises only if multiple thread reads and write to a shared state. Multiple reads won't cause any issue here. – Ravindra Ranwala Aug 31 '19 at 06:31
  • 1
    As long as you don't try to reconfigure it, it should be fine. I you have a lot of different configuration for different requests, consider making those configurations on the WebTarget. Almost everything that can be configured on the Client, can also be configured on the WebTarget. Getting new WebTargets is thread-safe. Just get the WebTarget and you don't have to worry about the Client anymore. – Paul Samsotha Aug 31 '19 at 08:30
  • @RavindraRanwala The problem is that different users sending request to `TestResource` have their own credentials for the `client`, so seems that different users have their own states on the client, I modified the question a bit accordingly – Rui Aug 31 '19 at 09:22
  • @PaulSamsotha I modified the question a bit that different requests indeed have different configurations – Rui Aug 31 '19 at 09:25
  • A header isn't a configuration. By the time you're calling the header method, you're no longer using the Client object. It's an Invocation.Builder. Why don't instead of chaining all the calls, assign each call to a typed variable. You will see that you are no longer using the Client once you call `client.target()`. Once you call that, you are at the `WebTarget`. No need to worry about the `Client` and thread-safety. – Paul Samsotha Aug 31 '19 at 16:52
  • @PaulSamsotha the ClientUtil.getInstance() returns the singleton Client instance initially retrieved by calling ClientBuilder.newClient(). Then in the update method body, the method chain starts from client.getTarget()... So on base of this seems that the singleton here is thread safe because there is no extra confoguration on the singleton Client instance, isn't it? – Rui Aug 31 '19 at 17:35
  • You should be good – Paul Samsotha Aug 31 '19 at 17:49
  • @PaulSamsotha so do you mean the method chain call in `Client` is thread safe? :) would like to confirm – Rui Aug 31 '19 at 18:23

0 Answers0