users@jersey.java.net

Issues with POST on a sub-resource

From: Arul Dhesiaseelan <arul_at_fluxcorp.com>
Date: Mon, 20 Oct 2008 10:30:21 -0600

Hi,

I am having issues with creating a sub-resource (using POST). I am
attaching the test case for my use case. I used Jersey 1.0 for this
testing. May be I am missing something completely.

I get the following exception when I try to create a new customer using
a sub-resource:

Oct 20, 2008 10:22:52 AM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
  sample
Oct 20, 2008 10:22:52 AM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Root resource classes found:
  class sample.TestSubResource$JerseyResource
Oct 20, 2008 10:22:52 AM com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Provider classes found:
Oct 20, 2008 10:22:52 AM com.sun.grizzly.http.servlet.ServletAdapter service
SEVERE: service exception:
javax.servlet.ServletException:
com.sun.jersey.api.container.ContainerException: Exception injecting
parameters to dynamic resolving method
    at
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:346)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:820)
    at
com.sun.grizzly.http.servlet.FilterChainImpl.doFilter(FilterChainImpl.java:141)
    at
com.sun.grizzly.http.servlet.ServletAdapter.service(ServletAdapter.java:233)
    at
com.sun.grizzly.tcp.http11.GrizzlyAdapter.service(GrizzlyAdapter.java:147)
    at
com.sun.grizzly.http.DefaultProcessorTask.invokeAdapter(DefaultProcessorTask.java:625)
    at
com.sun.grizzly.http.DefaultProcessorTask.doProcess(DefaultProcessorTask.java:562)
    at
com.sun.grizzly.http.DefaultProcessorTask.process(DefaultProcessorTask.java:819)
    at
com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:152)
    at
com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:136)
    at
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:103)
    at
com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:89)
    at
com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
    at
com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:67)
    at
com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:56)
    at
com.sun.grizzly.util.WorkerThreadImpl.processTask(WorkerThreadImpl.java:325)
    at com.sun.grizzly.util.WorkerThreadImpl.run(WorkerThreadImpl.java:184)
Caused by: com.sun.jersey.api.container.ContainerException: Exception
injecting parameters to dynamic resolving method
    at
com.sun.jersey.impl.uri.rules.SubLocatorRule.invokeSubLocator(SubLocatorRule.java:119)
    at
com.sun.jersey.impl.uri.rules.SubLocatorRule.accept(SubLocatorRule.java:75)
    at
com.sun.jersey.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
    at
com.sun.jersey.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:71)
    at
com.sun.jersey.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:111)
    at
com.sun.jersey.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:63)
    at
com.sun.jersey.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:722)
    at
com.sun.jersey.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:692)
    at
com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:344)
    ... 16 more
Caused by: java.lang.NullPointerException
    at
com.sun.jersey.impl.uri.rules.SubLocatorRule.invokeSubLocator(SubLocatorRule.java:103)
    ... 24 more

com.sun.jersey.api.client.UniformInterfaceException: Status: 500
    at com.sun.jersey.api.client.WebResource.handle(WebResource.java:468)
    at com.sun.jersey.api.client.WebResource.access$200(WebResource.java:64)
    at
com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:404)
    at
sample.TestSubResource.testCustomerSubResource(TestSubResource.java:176)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at
com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:90)


Appreciate any insight into this issue.

Thanks!
Arul



package sample;

import com.sun.grizzly.http.SelectorThread;
import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.container.grizzly.GrizzlyWebContainerFactory;
import junit.framework.TestCase;

import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.IOException;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;

public class TestSubResource extends TestCase {

  private SelectorThread threadSelector;

  private static final String JERSEY_HTTP_TEST_PORT = "9191";

  protected WebResource r;

  protected Client c;

  /**
   * Get the base URI for the Web application.
   *
   * @return the base URI.
   */
  private static URI getBaseURI() {
    return UriBuilder.fromUri("http://localhost/rest").port(getPort(9998)).build();
  }

  /**
   * The base URI of the Web application.
   */
  public static final URI BASE_URI = getBaseURI();

  /**
   * Get the HTTP port for the Web application.
   *
   * @param defaultPort the default HTTP port to use.
   * @return the HTTP port.
   */
  private static int getPort(int defaultPort) {
    String port = JERSEY_HTTP_TEST_PORT;
    if (null != port) {
      try {
        return Integer.parseInt(port);
      } catch (NumberFormatException e) {
      }
    }
    return defaultPort;
  }

  /**
   * Start the Grizzly HTTP Container.
   *
   * @return SelectorThread the Grizzly selector thread.
   * @throws java.io.IOException if there is an error starting the Grizzly
   * HTTP container.
   */
  protected static SelectorThread startServer() throws IOException {
    final Map<String, String> initParams = new HashMap<String, String>();

    initParams.put("com.sun.jersey.config.property.packages", "sample");
    System.out.println("Starting grizzly...");
    return GrizzlyWebContainerFactory.create(BASE_URI, initParams);
  }

  public TestSubResource() {
  }

  public TestSubResource(String testName) {
    super(testName);
  }

  @Override
  protected void setUp() throws Exception {
    super.setUp();

    //start the Grizzly web container and create the client
    threadSelector = startServer();

    c = Client.create();
    r = c.resource(BASE_URI);
  }

  @Override
  protected void tearDown() throws Exception {
    super.tearDown();

    threadSelector.stopEndpoint();
  }


  @Path("/customerservice")
  public static class JerseyResource {
    @Context
    UriInfo uriInfo;
    @Context
    Request request;


    public JerseyResource(UriInfo uriInfo, Request request) {
      this.uriInfo = uriInfo;
      this.request = request;
    }

    @Path("customers")
    public CustomerResource getCustomerResource(Customer pojo) {
      return new CustomerResource(uriInfo, request, pojo);
    }

  }

  public static class CustomerResource {
    @Context
    UriInfo uriInfo;
    @Context
    Request request;
    Customer customer;

    public CustomerResource(UriInfo uriInfo, Request request, Customer customer) {
      this.uriInfo = uriInfo;
      this.request = request;
      this.customer = customer;
    }

    @POST
    @Consumes("application/xml")
    @Produces("application/xml")
    public Customer addCustomer() {
      URI uri = uriInfo.getAbsolutePath();
      customer.setUri(uri.toString());
      return customer;
    }
  }

  @XmlRootElement
  static class Customer {
    private String name;
    private String uri;


    public String getName() {
      return name;
    }

    public void setName(String name) {
      this.name = name;
    }

    public String getUri() {
      return uri;
    }

    public void setUri(String uri) {
      this.uri = uri;
    }
  }

  public void testCustomerSubResource() {
    Customer pojo = new Customer();
    pojo.setName("joe");

    Customer mojo = r.path("customerservice").path("customers").type(MediaType.APPLICATION_XML).post(Customer.class, pojo);
    assertEquals(pojo.getName(), mojo.getName());

  }
}