JAX-RS service 404 error: No root resource matching requested path
oren Jun 19, 2009 3:10 PMDear All,
I am badly stuck on the following issue. I wrote a JAX-RS-annotated web service POJO and deployed it to FUSE ESB 4.1.0.0 using the CXF <jaxrs:server> annotation in the bundle-context.xml file of the bundle. The main CXF services page shows that the service is registered under /fqe. However, when I hit a service method in my browser, jetty reports an HTTP 404 error (URL not found). I tried many different configurations according to forum postings, e.g. deploying the service programmatically in the afterPropertiesSet() method instead of in the XML context file -- commented in the code below, but none work.
I also tried the standard Spring DM weather service example by Roberto Rojas, and this produced exactly the same behavior. Can you please advise on how to correctly implement JAX-RS web services in FUSE ESB?
Thank you in advance.
-
FqeServiceFrontEndImpl.java -
/*******************************************************************************
Source File: FqeServiceFrontEnd.java
******************************************************************************/
package edu.utah.further.fqe.fqe_bc_ws;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.ProduceMime;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import edu.utah.further.fqe.fqe_bc.api.FqeClient;
import edu.utah.further.fqe.fqe_se_simple.SimpleService;
/**
A web service that exposes internal services.
<p>
-----------------------------------------------------------------------------------<br>
(c) 2008-2009 FURTHeR Project, Health Sciences IT, University of Utah<br>
Contact: Dr. Scott Narus<code><scott.narus@hsc.utah.edu></code><br>
Biomedical Informatics, 26 South 2000 East<br>
Room 5775 HSEB, Salt Lake City, UT 84112<br>
Day Phone: 1-801-213-3288<br>
-----------------------------------------------------------------------------------
*
@author Oren E. Livne <code><oren.livne@utah.edu></code>
@version May 29, 2009
*/
@Path("/services")
// @WebService
// @ProduceMime("application/xml")
public class FqeServiceFrontEndImpl implements InitializingBean, DisposableBean
{
// ========================= CONSTANTS =================================
private static final Logger logger = LoggerFactory
.getLogger(FqeServiceFrontEndImpl.class);
// ========================= DEPENEDENCIES =============================
private FqeClient fqeClient;
private SimpleService simpleService;
// ========================= METHODS ===================================
/**
@throws Exception
@see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@PostConstruct
public void afterPropertiesSet() throws Exception
{
if (logger.isDebugEnabled())
{
logger.debug("Initializing the federated query front-end web service");
}
// JaxWsServerFactoryBean sf = new JaxWsServerFactoryBean();
// sf.setServiceClass(getClass());
// sf.setBindingId(HttpBindingFactory.HTTP_BINDING_ID);
// sf.setAddress("http://localhost:8080/fqe");
// sf.getServiceFactory().setInvoker(new BeanInvoker(this));
// JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
// sf.setResourceClasses(FqeServiceFrontEndImpl.class);
// sf.setResourceProvider(FqeServiceFrontEndImpl.class,
// new SingletonResourceProvider(this));
// sf.setBindingId(JAXRSBindingFactory.JAXRS_BINDING_ID);
// sf.setAddress("/fqe");
//
// BindingFactoryManager manager = sf.getBus().getExtension(
// BindingFactoryManager.class);
// JAXRSBindingFactory factory = new JAXRSBindingFactory();
// factory.setBus(sf.getBus());
// manager.registerBindingFactory(JAXRSBindingFactory.JAXRS_BINDING_ID, factory);
// sf.create();
if (logger.isDebugEnabled())
{
logger.debug("Done initializing the federated query front-end web service");
}
}
/**
@throws Exception
@see org.springframework.beans.factory.DisposableBean#destroy()
*/
@PreDestroy
public void destroy()
{
if (logger.isDebugEnabled())
{
logger.debug("Shutting down the federated query front-end web service");
}
}
// ========================= IMPLEMENTATION: FqeServiceFrontEnd ========
/**
@param message
@return
@see edu.utah.further.fqe.fqe_bc_ws.FqeServiceFrontEnd#sayHello(java.lang.String)
*/
@GET
@ProduceMime("application/text")
@Path("/hello/")
// @Get
// @HttpResource(location = "
hello
")
public String sayHello(final String message)
{
// String helloOutput = simpleService.sayHello(message);
String helloOutput = "Hello " + message;
// final StringBuilder xml = new StringBuilder(
// "");
// // xml.append(fqeClient.getDataSourceStatus());
// return xml.toString();
return helloOutput;
}
/**
@return
@see edu.utah.further.fqe.fqe_bc_ws.FqeServiceFrontEnd#getDataSourceStatus()
*/
// @GET
// @Path("/status")
public String getDataSourceStatus()
{
// fqeClient.getDataSourceStatus();
final StringBuilder xml = new StringBuilder(
"");
// xml.append(fqeClient.getDataSourceStatus());
return xml.toString();
}
// ========================= GETTERS & SETTERS =========================
/**
@param FqeClient
@see edu.utah.further.fqe.fqe_bc_ws.FqeServiceFrontEnd#setFqeClient(edu.utah.further.fqe.fqe_bc.api.FqeClient)
*/
public void setFqeClient(final FqeClient FqeClient)
{
if (logger.isDebugEnabled())
{
logger.debug("Setting FqeClient: " + FqeClient);
}
this.fqeClient = FqeClient;
}
/**
@param simpleService
@see edu.utah.further.fqe.fqe_bc_ws.FqeServiceFrontEnd#setSimpleService(edu.utah.further.fqe.fqe_se_simple.SimpleService)
*/
public void setSimpleService(final SimpleService simpleService)
{
if (logger.isDebugEnabled())
{
logger.debug("Setting SimpleService: " + simpleService);
}
this.simpleService = simpleService;
}
}
-
bundle-context.xml -
-
Browser output for http://localhost:8080/cxf
HelloWorldImplPort
FqeServiceFrontEndImpl
WeatherServiceFrontEnd
-
Browser output for http://localhost:8080/cxf/fqe/hello/message
XML Parsing Error: no element found
Location: http://localhost:8080/cxf/fqe/hello/message
Line Number 1, Column 1:
^
(i.e. empty document)
ServiceMix log shows:
13:06:46,889 | DEBUG | qe/hello/message | jetty | .service.internal.util.JCLLogger 85 | REQUEST /cxf/fqe/hello/message on org.mortbay.jetty.HttpConnection@1a8b29c
13:06:46,889 | DEBUG | qe/hello/message | ServerModel | rvice.internal.model.ServerModel 265 | Matching /cxf/fqe/hello/message...
13:06:46,889 | DEBUG | qe/hello/message | ServerModel | rvice.internal.model.ServerModel 283 | Path /cxf/fqe/hello/message matched to {pattern=/cxf/.,model=ServletModel{id=org.ops4j.pax.web.service.internal.model.ServletModel-2,name=cxf-transport-osgi-servlet,urlPatterns=[/cxf/],alias=/cxf,servlet=org.apache.servicemix.cxf.transport.http_osgi.SpringOsgiServlet@227bd0,initParams={org.springframework.osgi.bean.name=osgiServlet, alias=/cxf, service.id=91, objectClass=[Ljava.lang.String;@c83cfd, Bundle-SymbolicName=org.apache.servicemix.cxf.transport.osgi, servlet-name=cxf-transport-osgi-servlet, Bundle-Version=4.1.0.fuse},context=ContextModel{id=org.ops4j.pax.web.service.internal.model.ContextModel-1,name=,httpContext=DefaultHttpContext{bundle=org.apache.servicemix.cxf.transport.osgi },contextParams={}}}}
13:06:46,889 | DEBUG | qe/hello/message | HttpServiceContext | vice.internal.HttpServiceContext 107 | Handling request for /cxf/fqe/hello/message using http context [DefaultHttpContext{bundle=org.apache.servicemix.cxf.transport.osgi }]
13:06:46,889 | DEBUG | qe/hello/message | jetty | .service.internal.util.JCLLogger 85 | sessionManager=org.mortbay.jetty.servlet.HashSessionManager@2ab836
13:06:46,889 | DEBUG | qe/hello/message | jetty | .service.internal.util.JCLLogger 85 | session=null
13:06:46,889 | DEBUG | qe/hello/message | jetty | .service.internal.util.JCLLogger 85 | servlet=cxf-transport-osgi-servlet
13:06:46,889 | DEBUG | qe/hello/message | jetty | .service.internal.util.JCLLogger 85 | chain=null
13:06:46,889 | DEBUG | qe/hello/message | jetty | .service.internal.util.JCLLogger 85 | servlet holder=cxf-transport-osgi-servlet
13:06:46,889 | WARN | qe/hello/message | JAXRSInInterceptor | .cxf.phase.PhaseInterceptorChain 236 | .No root resource matching request path /cxf/fqe/hello/message is found.
13:06:46,889 | WARN | qe/hello/message | WebApplicationExceptionMapper | pache.cxf.jaxrs.utils.JAXRSUtils 968 | WebApplicationException has been caught : no cause is available
13:06:46,889 | DEBUG | qe/hello/message | jetty | .service.internal.util.JCLLogger 85 | RESPONSE /cxf/fqe/hello/message 404
-
ServiceMix Log When bundle is deployed to bus -
12:59:47,904 | DEBUG | tenderThread-103 | DefaultListableBeanFactory | ractAutowireCapableBeanFactory$1 411 | Finished creating instance of bean 'org.apache.cxf.jaxrs.JAXRSBindingFactory'
12:59:47,904 | DEBUG | tenderThread-103 | DefaultListableBeanFactory | tory.support.AbstractBeanFactory 214 | Returning cached instance of singleton bean 'org.apache.cxf.jaxrs.JAXRSBindingFactory'
12:59:47,904 | INFO | tenderThread-103 | ServerImpl | cxf.jaxrs.JAXRSServerFactoryBean 86 | Setting the server's publish address to be /fqe
12:59:47,904 | DEBUG | tenderThread-103 | DefaultListableBeanFactory | ractAutowireCapableBeanFactory$1 411 | Finished creating instance of bean 'fqeService'
12:59:47,904 | DEBUG | tenderThread-103 | DefaultListableBeanFactory | tory.support.AbstractBeanFactory 214 | Returning cached instance of singleton bean 'cxf'
12:59:47,904 | DEBUG | tenderThread-103 | DefaultListableBeanFactory | tory.support.AbstractBeanFactory 214 | Returning cached instance of singleton bean 'org.apache.cxf.buslifecycle.BusLifeCycleManager'
12:59:47,904 | INFO | tenderThread-103 | OsgiBundleXmlApplicationContext | ractOsgiBundleApplicationContext 324 | Publishing application context as OSGi service with properties {org.springframework.context.service.name=edu.utah.further.fqe.fqe-bc-ws, Bundle-SymbolicName=edu.utah.further.fqe.fqe-bc-ws, Bundle-Version=1.0.0.SNAPSHOT}
12:59:47,904 | DEBUG | tenderThread-103 | OsgiBundleXmlApplicationContext | ractOsgiBundleApplicationContext 338 | Publishing service under classes {org.springframework.osgi.context.DelegatedExecutionOsgiBundleApplicationContext, org.springframework.osgi.context.ConfigurableOsgiBundleApplicationContext, org.springframework.context.ConfigurableApplicationContext, org.springframework.context.ApplicationContext, org.springframework.context.Lifecycle, org.springframework.beans.factory.ListableBeanFactory, org.springframework.beans.factory.HierarchicalBeanFactory, org.springframework.context.MessageSource, org.springframework.context.ApplicationEventPublisher, org.springframework.core.io.support.ResourcePatternResolver, org.springframework.beans.factory.BeanFactory, org.springframework.core.io.ResourceLoader, org.springframework.beans.factory.DisposableBean}
12:59:47,904 | DEBUG | tenderThread-103 | fqe-bc-ws | ? ? | ServiceEvent REGISTERED
12:59:47,904 | DEBUG | tenderThread-103 | SpringApplicationListener | l.osgi.SpringApplicationListener 80 | Spring app state changed to Started for bundle 121
12:59:53,342 | DEBUG | 6@qtp1-0 - /cxf/ | jetty | .service.internal.util.JCLLogger 85 | REQUEST /cxf/ on org.mortbay.jetty.HttpConnection@115a928
12:59:53,342 | DEBUG | 6@qtp1-0 - /cxf/ | ServerModel | rvice.internal.model.ServerModel 265 | Matching /cxf/...
12:59:53,342 | DEBUG | 6@qtp1-0 - /cxf/ | ServerModel | rvice.internal.model.ServerModel 283 | Path /cxf/ matched to {pattern=/cxf/.,model=ServletModel{id=org.ops4j.pax.web.service.internal.model.ServletModel-2,name=cxf-transport-osgi-servlet,urlPatterns=[/cxf/],alias=/cxf,servlet=org.apache.servicemix.cxf.transport.http_osgi.SpringOsgiServlet@227bd0,initParams={org.springframework.osgi.bean.name=osgiServlet, alias=/cxf, service.id=91, objectClass=[Ljava.lang.String;@c83cfd, Bundle-SymbolicName=org.apache.servicemix.cxf.transport.osgi, servlet-name=cxf-transport-osgi-servlet, Bundle-Version=4.1.0.fuse},context=ContextModel{id=org.ops4j.pax.web.service.internal.model.ContextModel-1,name=,httpContext=DefaultHttpContext{bundle=org.apache.servicemix.cxf.transport.osgi },contextParams={}}}}