3

I have a PostgreSQL table testtable with a two part primary key (ID1 of type bigint, ID2 of type bigint) and a non-key field with a timestamp. I am trying to generate a RESTful webservice using the "New RESTful Web Services from Database" wizard and, except for the package name (service) selecting the default for all of the values. The wizard produces four files:

  • AbstractFacade.java
  • Testtable.java
  • TesttableREST.java
  • TesttablePK.java

Deploying to the server, and selecting "Test RESTful Web Services", the test page fails to load with:

exception 
javax.servlet.ServletException: PWC1391: Servlet.init() for servlet org.netbeans.rest.application.config.ApplicationConfig threw exception

root cause 
com.sun.jersey.spi.inject.Errors$ErrorMessagesException

Looking in the glassfish event log, there are two severe errors:

The following errors and warnings have been detected with resource and/or provider classes:
SEVERE: Missing dependency for method public void service.TesttableFacadeREST.remove(service.TesttablePK) at parameter at index 0
SEVERE: Method, public void service.TesttableFacadeREST.remove(service.TesttablePK), annotated with DELETE of resource, class service.TesttableFacadeREST, is not recognized as valid resource method.
SEVERE: Missing dependency for method public service.Testtable service.TesttableFacadeREST.find(service.TesttablePK) at parameter at index 0
SEVERE: Method, public service.Testtable service.TesttableFacadeREST.find(service.TesttablePK), annotated with GET of resource, class service.TesttableFacadeREST, is not recognized as valid resource method. 

and

WebModule[/tabletest]StandardWrapper.Throwable com.sun.jersey.spi.inject.Errors$ErrorMessagesException
    at com.sun.jersey.spi.inject.Errors.processErrorMessages(Errors.java:170)
    at com.sun.jersey.spi.inject.Errors.postProcess(Errors.java:136)
    at com.sun.jersey.spi.inject.Errors.processWithErrors(Errors.java:199)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:771)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.initiate(WebApplicationImpl.java:766)
    at com.sun.jersey.spi.container.servlet.ServletContainer.initiate(ServletContainer.java:488)
    at com.sun.jersey.spi.container.servlet.ServletContainer$InternalWebComponent.initiate(ServletContainer.java:318)
    at com.sun.jersey.spi.container.servlet.WebComponent.load(WebComponent.java:609)
    at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:210)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:373)
    at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:556)
    at javax.servlet.GenericServlet.init(GenericServlet.java:244)
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1453)
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:1093)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:189)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
    at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
    at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:161)
    at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:331)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
    at com.sun.enterprise.v3.services.impl.ContainerMapper$AdapterCallable.call(ContainerMapper.java:317)
    at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:195)
    at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:860)
    at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:757)
    at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1056)
    at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:229)
    at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
    at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
    at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
    at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
    at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
    at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
    at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
    at java.lang.Thread.run(Thread.java:722) 

Before I go haring off to file a bug report with NetBeans, I just wanted to see if this was more likely a developer error rather than an error with the developer's toolset. Thoughts?

  • Database: PostgreSQL 8.4
  • App Server: Glassfish 3.1.2.2
  • IDE: NetBeans 7.2
  • JDK: 7 update 7
andand
  • 17,134
  • 11
  • 53
  • 79

1 Answers1

1

The problem arises because the remove and find method both use the TesttablePK type in conjunction with @PathParam but Jersey cannot find a way to convert the string from the url to such an object. This can be solved by modifying the TesttablePK type. You have two choices:

  • add a constructor that accepts a single String argument.
  • or add a static method named valueOf or fromString that accepts a single String argument

So you will need to decide how you are going to represent the composite key as a string and convert such a string to the TesttablePK type.

Eelke
  • 20,897
  • 4
  • 50
  • 76
  • I'll give it a try. Also, is this documented anywhere? This is the second question like this you've answered for me, so you're either speaking from much more experience or you have access to docs I know nothing of. Thanks. – andand Oct 20 '12 at 14:46
  • 1
    More docs then experience in this case as I haven't yet used a composite key with a restfull service. I saw in the generated code that the only two routines causing errors were the only two using the composite key type as a parameter so I started to suspect that the problem was the conversion from the value in the URL to the required type. So I looked up @PathParam docs: http://jsr311.java.net/nonav/releases/1.1/javax/ws/rs/PathParam.html in the hope they would clearup how the conversion is done. The Jersey manual: http://jersey.java.net/nonav/documentation/latest/index.html – Eelke Oct 20 '12 at 15:34