Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reusing JAX RS Client in multi-threaded environment (with resteasy)

According to the documentation,

"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. "

Ok, I'm trying to cache Client itself and WebTarget instances in a static variable, the someMethod() is invoked in multi-threaded environment:

private static Client client = ClientBuilder.newClient();
private static WebTarget webTarget = client.target("someBaseUrl");
...
public static String someMethod(String arg1, String arg2)
{
    WebTarget target = entrTarget.queryParam("arg1", arg1).queryParam("arg2", arg2);
    Response response = target.request().get();
    final String result = response.readEntity(String.class);
    response.close();
    return result;
}

But sometimes (not always) I'm get an exception:

Invalid use of BasicClientConnManager: connection still allocated. Make sure to release the connection before allocating another one.

How can Client/WebTarget be reused/cached correctly? Is it possible with JAX RS Client API? Or I have to use some framework-specific features (resteasy/jersey) Could you provide some example or documentation?

like image 247
Alexandr Avatar asked Oct 13 '15 08:10

Alexandr


People also ask

Is RESTEasy client thread safe?

No, by default the ResteasyClient is not thread safe because of it's underlying HTTP dependencies.

What is RESTEasy client?

RESTeasy is a Java library that provides a simple interface to the REST server. It supports all of the features of the Jakarta REST Services and includes support for both synchronous and asynchronous communication. Firstly, there are really two ways to create a REST Client. Use Jakarta REST Client API.

What is JBoss RESTEasy?

RESTEasy is a JBoss project that provides various frameworks to help you build RESTful Web Services and RESTful Java applications. It is a portable implementation of the Jakarta RESTful Web Services specification. The Jakarta RESTful Web Services provides a Java API for RESTful Web Services over the HTTP protocol.

What is Jax RS Client API?

The JAX-RS client API is a Java based API used to access Web resources. It is not restricted to resources implemented using JAX-RS.


1 Answers

Your implementation is not thread-safe. When two threads access someMethod at the same time they are sharing the same Client and one will try to make a second request while the first one is not finished.

You have two choices:

  • Synchronize the access to the Client and WebTarget manually.
  • Let the container manage concurrency by annotating the enclosing type with @javax.ejb.Singleton which guarantees thread safety. (see chapter 4.8.5 of the EJB specification)

If someMethod in a container managed environment I would use the second approach.

like image 170
lefloh Avatar answered Oct 11 '22 13:10

lefloh