users@jersey.java.net

[Jersey] Re: Thread safe question for Jersey client - aka Java threading 101

From: Sobieralski, Damian Michael <dsobiera_at_indiana.edu>
Date: Fri, 12 Dec 2014 03:01:35 +0000

The interesting part is that this service is injected via hk2 from a Jersey @GET endpoint. MyAppleService extends the base class given earlier (with the protected Client and WebTarget). So, MyAppleService is what is in question and below is “how it is called”. So Jersey server stuff is calling the service which in turn calls a another REST ws via Jersey client. It’s not quite as simple but this should accurately illustrate how this is called.

@Path("/apples")
public class MyJerseyRestWebservice {

                private static final Logger logger = Logger.getLogger(MyJerseyRestWebservice.class.getName());

                @Inject
                 public MyAppleService myAppleService;


                  @GET
                  @Path("{appleId}")
                  @Produces( {MediaType.APPLICATION_JSON, MediaType.TEXT_XML, MediaType.TEXT_PLAIN, MediaType.TEXT_HTML })
                  public Apple getApple(@PathParam("appleId") String appleId ){

                   Apple apple = myAppleService.getApple(appleId);

                      return apple;
                  }



public class ApplicationBinder extends AbstractBinder {

    protected void configure() {
        bind(MyAppleServiceImpl.class).to(MyAppleService.class);
    }
}

Thanks for any guidance that you can give.

- Damian


From: Moises Lejter [mailto:moilejter_at_gmail.com]
Sent: Thursday, December 11, 2014 7:10 PM
To: users_at_jersey.java.net
Subject: [Jersey] Re: Thread safe question for Jersey client - aka Java threading 101

But the question is not just whether Jersey itself is thread-safe, but whether this code that calls it would be. And I think the answer to that latter is "no" ... If the instance that has the jerseyTarget variable can be used by multiple threads, it is possible that from any one thread's perspective, the value of the variable could change in between two uses of that variable in that thread - which probably is not what the thread expected would happen?

I would think either that instance that has the jerseyTarget is already itself MT-safe, or you could do things like making jerseyTarget use ThreadLocal storage, so that different threads would each get their own instance...

Moises


On Thu, Dec 11, 2014 at 11:38 AM, cowwoc <cowwoc_at_bbs.darktech.org<mailto:cowwoc_at_bbs.darktech.org>> wrote:
Hi Damian,

I don't see why either case is a threading problem.

If Client and WebTarget are thread-safe (JAX-RS doesn't indicate either way, but unofficially they are supposed to be) then either approach would work fine.

Gili


On 11/12/2014 11:32 AM, Sobieralski, Damian Michael wrote:
I have a question about thread safety here. This is a much lower level discussion than what have been reading here and touches on Java threading 101.

In a backend service object (we have something like this - this object sits in a servlet container):

protected Client jerseyClient = null;
protected WebTarget jerseyTarget = null;

These are class variables. This is normally a warning flag for threading issues

Then we have code like this:

        protected void readyConnection() throws Exception {
            jerseyClient = ClientBuilder.newBuilder().register(JacksonFeature.class).build();

           jerseyTarget = jerseyClient.target(baseUrl).path("api").path("v1");
        }

and methods that use jerseyTarget. Is this a bad idea thread wise? It seems like jersey client is fine being a class variable. But that jerseyTarget in this ready method instead of setting the class variable jerseyTarget should return its own jerseyTarget.

So, is it better to do this?

        protected WebTarget readyConnection() throws Exception {
            jerseyClient = ClientBuilder.newBuilder().register(JacksonFeature.class).build();

           return jerseyClient.target(baseUrl).path("api").path("v1");
        }

- Damian