I'm calling a REST service using this test code:
public class TestRESTServices {
private static final String BASE_URL = "http://localhost/ma.ge.persistence-1.0/rest/reference";
private static URI uri = UriBuilder.fromUri(BASE_URL).port(8080).build();
private static Client client = ClientBuilder.newClient();
@Test
public void createAndDeleteAReference() {
Reference r = ReferenceFactory.createReference("Maz",
"dummy", 1.7);
Response response = client.target(uri).request().post(Entity.entity(r, MediaType.APPLICATION_JSON));
assertEquals(Response.Status.CREATED, response.getStatusInfo());
URI referenceURI = response.getLocation();
// Get the posted reference
response = client.target(referenceURI).request().get();
Reference retreivedRef = response.readEntity(Reference.class);
assertEquals(Response.Status.OK, response.getStatusInfo());
assertEquals(retreivedRef.getName(), r.getName());
}
But I get the following error:
javax.ws.rs.ProcessingException: Unable to invoke request at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:287) at org.jboss.resteasy.client.jaxrs.internal.ClientInvocation.invoke(ClientInvocation.java:407) at org.jboss.resteasy.client.jaxrs.internal.ClientInvocationBuilder.get(ClientInvocationBuilder.java:159) at ma.gesto.persistence.TestRESTServices.createAndDeleteAReference(TestRESTServices.java:34) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) at org.junit.runners.ParentRunner.run(ParentRunner.java:309) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) Caused by: java.lang.IllegalStateException: Invalid use of BasicClientConnManager: connection still allocated. Make sure to release the connection before allocating another one. at org.apache.http.impl.conn.BasicClientConnectionManager.getConnection(BasicClientConnectionManager.java:162) at org.apache.http.impl.conn.BasicClientConnectionManager$1.getConnection(BasicClientConnectionManager.java:139) at org.apache.http.impl.client.DefaultRequestDirector.execute(DefaultRequestDirector.java:456) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:906) at org.apache.http.impl.client.AbstractHttpClient.execute(AbstractHttpClient.java:805) at org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient4Engine.invoke(ApacheHttpClient4Engine.java:283) ... 26 more
The Client
interface represents external resources. As such, it is a critical mistake to create and store one in a static variable. This is wrong:
private static Client client = ClientBuilder.newClient();
This is ok for unit testing:
private Client client;
@Before
public void setUp() {
this.client = ClientBuilder.newClient();
}
@After
public void tearDown() {
this.client.close();
}
In normal code you would want to wrap Client
usage in a try-with-resources
or try..finally
:
Client client = ClientBuilder.newClient();
try {
// use the client to make requests
} finally {
client.close();
}
Ideally there would be a way to manage a pool of Client
instances for reuse.
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