I try to create a wadl from an existing CXF rest service. It does not work. I am getting instead HTTP 404. The rest service itself does work. I use Tomcat 7.
What am I doing wrong?
Server Information
Tomcat Version JVM Version JVM Vendor OS Name OS Version OS Architecture Hostname IP Address
Apache Tomcat/7.0.52 (Ubuntu) 1.7.0_72-b14 Oracle Corporation Linux 3.13.0-43-generic amd64 myself 127.0.1.1
/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-cxf-rest-example.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>
org.apache.cxf.transport.servlet.CXFServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
</web-app>
/WEB-INF/spring-cxf-rest-example.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxrs="http://cxf.apache.org/jaxrs"
xmlns:cxf="http://cxf.apache.org/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/jaxrs http://cxf.apache.org/schemas/jaxrs.xsd
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd">
<context:component-scan base-package="com.myself" />
<jaxrs:server id="exampleCxfServer" address="/">
<jaxrs:serviceBeans>
<ref bean="exampleService"/>
</jaxrs:serviceBeans>
<jaxrs:extensionMappings>
<entry key="json" value="application/json"/>
</jaxrs:extensionMappings>
<jaxrs:features>
<cxf:logging/>
</jaxrs:features>
<jaxrs:providers>
<bean class="com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider" />
</jaxrs:providers>
</jaxrs:server>
</beans>
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.myself</groupId>
<artifactId>cxf3example</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>cxf3example Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<spring.version>4.0.0.RELEASE</spring.version>
<cxf.version>3.0.0</cxf.version>
<jackson.version>2.0.1</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-frontend-jaxrs</artifactId>
<version>${cxf.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.jaxrs</groupId>
<artifactId>jackson-jaxrs-json-provider</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<!--
<source>1.8</source>
<target>1.8</target>
-->
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
<finalName>cxf3example</finalName>
</build>
</project>
ExampleService.java
package com.myself.service;
import com.myself.model.ExampleModel;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
@Path("/example")
@Produces("application/json")
public interface ExampleService {
@GET
@Path("/{id}")
public ExampleModel get(@PathParam("id") String id);
}
ExampleServiceImpl.java
package com.myself.service;
import com.myself.model.ExampleModel;
import org.springframework.stereotype.Service;
@Service("exampleService")
public class ExampleServiceImpl implements ExampleService {
@Override
public ExampleModel get(String modelId) {
return new ExampleModel("example", 1001);
}
}
ExampleModel.java
package com.myself.model;
public class ExampleModel {
private String string;
private int anInt;
public ExampleModel() {}
public ExampleModel(String string, int anInt) {
this.string = string;
this.anInt = anInt;
}
public String getString() {
return string;
}
public void setString(String string) {
this.string = string;
}
public int getAnInt() {
return anInt;
}
public void setAnInt(int anInt) {
this.anInt = anInt;
}
@Override
public String toString() {
return "ExampleModel{" +
"string='" + string + '\'' +
", anInt=" + anInt +
'}';
}
}
This request works:
http://localhost:8080/cxf3example/services/example/1
catalina.out:
Feb 04, 2015 5:43:27 PM org.apache.cxf.interceptor.LoggingInInterceptor
INFO: Inbound Message
----------------------------
ID: 1
Address: http://localhost:8080/cxf3example/services/example/1
Http-Method: GET
Content-Type:
Headers: {Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8], accept-encoding=[gzip, deflate], accept-language=[en-US,en;q=0.5], connection=[keep-alive], Content-Type=[null], host=[localhost:8080], user-agent=[Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:34.0) Gecko/20100101 Firefox/34.0]}
--------------------------------------
Feb 04, 2015 5:43:27 PM org.apache.cxf.interceptor.LoggingOutInterceptor
INFO: Outbound Message
---------------------------
ID: 1
Response-Code: 200
Content-Type: application/json
Headers: {Content-Type=[application/json], Date=[Wed, 04 Feb 2015 22:43:27 GMT]}
Payload: {"string":"example","anInt":1001}
--------------------------------------
This request does NOT work:
http://localhost:8080/cxf3example/services/exampleService/?_wadl
catalina.out:
Feb 04, 2015 5:45:51 PM org.apache.cxf.interceptor.LoggingInInterceptor
INFO: Inbound Message
----------------------------
ID: 2
Address: http://localhost:8080/cxf3example/services/exampleService/?_wadl
Http-Method: GET
Content-Type:
Headers: {Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8], accept-encoding=[gzip, deflate], accept-language=[en-US,en;q=0.5], connection=[keep-alive], Content-Type=[null], host=[localhost:8080], user-agent=[Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:34.0) Gecko/20100101 Firefox/34.0]}
--------------------------------------
Feb 04, 2015 5:45:51 PM org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor processRequest
WARNING: No root resource matching request path /cxf3example/services/exampleService/ has been found, Relative Path: /exampleService/. Please enable FINE/TRACE log level for more details.
Feb 04, 2015 5:45:51 PM org.apache.cxf.jaxrs.impl.WebApplicationExceptionMapper toResponse
WARNING: javax.ws.rs.NotFoundException: HTTP 404 Not Found
at org.apache.cxf.jaxrs.utils.SpecExceptions.toNotFoundException(SpecExceptions.java:89)
at org.apache.cxf.jaxrs.utils.ExceptionUtils.toNotFoundException(ExceptionUtils.java:117)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.processRequest(JAXRSInInterceptor.java:167)
at org.apache.cxf.jaxrs.interceptor.JAXRSInInterceptor.handleMessage(JAXRSInInterceptor.java:76)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:307)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:243)
at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:223)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:197)
at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:149)
at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doGet(AbstractHTTPServlet.java:211)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:620)
at org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1040)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:607)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:313)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Feb 04, 2015 5:45:51 PM org.apache.cxf.interceptor.LoggingOutInterceptor
INFO: Outbound Message
---------------------------
ID: 2
Response-Code: 404
Content-Type:
Headers: {Date=[Wed, 04 Feb 2015 22:45:51 GMT], Content-Length=[0]}
--------------------------------------
By default, a basic WADL is generated at runtime and can be accessed from your REST web service by adding a GET to the /application. wadl resource at the base URI of your REST application. For example: GET http://<path_to_REST_app>/application.wadl .
WADL stands for Web Application Description Language which is a machine-readable language consisting of XML descriptions, which is based on HTTP web services.
Apache CXF™ is an open source services framework. CXF helps you build and develop services using frontend programming APIs, like JAX-WS and JAX-RS. These services can speak a variety of protocols such as SOAP, XML/HTTP, RESTful HTTP, or CORBA and work over a variety of transports such as HTTP, JMS or JBI.
I had to add to the dependencies:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-rs-service-description</artifactId>
<version>${cxf.version}</version>
</dependency>
Sadly, it fails without giving me an exception that something is missing on the classpath.
Also, as suggested by David J. Liszewski the correct URL is:
http://localhost:8080/cxf3example/services/example?_wadl
The service path component is declared as "/example".
Try http://localhost:8080/cxf3example/services/example?_wadl
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