Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

You must use at least one, but no more than one http method annotation on for reaseasy proxy client

I am trying to implement a simple client in rest easy, but I am getting an error saying "You must use at least one, but no more than one http method annotation". In my server implementation, I have added a http annotation on my method.

    @Path("/")
public class TestResource
{
    @GET
    @Path("/domain/{value}")
    public String get(@PathParam("value") final String value) {
        return "Hello" + value;
    }
}

I debugged it through, the first time it is not hitting the runtime exception, However, it is making a second call to it and failing, not sure why and how.

My client as junit test:

@Test
public void testPerformRestEasy() {

    ResteasyClient client = new ResteasyClientBuilder().build();
    ResteasyWebTarget target = client.target("http://localhost:8080/");
    TestResource proxy = target.proxy(TestResource.class);
    String response = proxy.get("user");
    Assert.assertEquals("Hellouser", response);
}

The code where it is failing

    private static <T> ClientInvoker createClientInvoker(Class<T> clazz, Method method, ResteasyWebTarget base, ProxyConfig config)
   {
      Set<String> httpMethods = IsHttpMethod.getHttpMethods(method);
      if (httpMethods == null || httpMethods.size() != 1)
      {
         throw new RuntimeException("You must use at least one, but no more than one http method annotation on: " + method.toString());
      }
      ClientInvoker invoker = new ClientInvoker(base, clazz, method, config);
      invoker.setHttpMethod(httpMethods.iterator().next());
      return invoker;
   }

Error:

java.lang.RuntimeException: You must use at least one, but no more than one http method annotation on: public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
    at org.jboss.resteasy.client.jaxrs.ProxyBuilder.createClientInvoker(ProxyBuilder.java:76)
    at org.jboss.resteasy.client.jaxrs.ProxyBuilder.proxy(ProxyBuilder.java:52)
    at org.jboss.resteasy.client.jaxrs.ProxyBuilder.build(ProxyBuilder.java:120)
    at org.jboss.resteasy.client.jaxrs.internal.ClientWebTarget.proxy(ClientWebTarget.java:72)

Does anyone know what the issue is here?

like image 538
LifeStartsAtHelloWorld Avatar asked Apr 21 '15 03:04

LifeStartsAtHelloWorld


2 Answers

The Resteasy JAXRS 2 client does not seem to accept implementation classes directly. To make it work, you have to create a properly annotated interface. It is used by Resteasy to generate a client proxy and your server must implement exactly the same interface.

So in your case, you have to split your code into an interface and a separate implementation class:

@Path("/")
public interface TestResource {
    @GET
    @Path("/domain/{value}")
    String get(@PathParam("value") final String value);
}

public class TestResourceImpl implements TestResource {
    @Override String get(final String value) {
        return "Hello" + value;
    }
}

I'm not sure if this is Resteasy-specific or required by the specification, but solved the same issue for me. You can find the section that gave me the hint here in the documentation.

like image 125
Zólyomi István Avatar answered Oct 16 '22 12:10

Zólyomi István


You have to define the MIME media type resource representation of resource(@Produces/@Consumes) from client. Like -

@Path("/")
public class TestResource
{
    @GET
    @Produces("text/plain")
    @Path("/domain/{value}")
    public String get(@PathParam("value") final String value) {
        return "Hello" + value;
    }
} 

The Jboss Client framework Doc will help you more.

like image 35
Sai prateek Avatar answered Oct 16 '22 12:10

Sai prateek