java.lang.ClassNotFoundException:javax.ws.rs.MessageProcessingException

时间:2015-01-09 20:44:22

标签: java tomcat cxf jax-rs jersey-client

我正在向Tomcat 7.0.57部署战争。此代码使用Jersey 2.x客户端与Rest端点进行通信,并使用CXF公开其自己的Rest端点(AKA the war' s端点)。

当我点击战争的一个端点时,代码似乎工作并从服务器的角度返回一个没有问题的响应,但客户端从tomcat返回500响应。这是错误:

java.lang.ClassNotFoundException: javax.ws.rs.MessageProcessingException
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
    org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
    org.apache.cxf.jaxrs.impl.ResponseBuilderImpl.build(ResponseBuilderImpl.java:69)
    org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.processResponse(JAXRSOutInterceptor.java:137)
    org.apache.cxf.jaxrs.interceptor.JAXRSOutInterceptor.handleMessage(JAXRSOutInterceptor.java:86)
    org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    org.apache.cxf.interceptor.OutgoingChainInterceptor.handleMessage(OutgoingChainInterceptor.java:77)
    org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:239)
    org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248)
    org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222)
    org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
    org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:167)
    org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
    org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:646)
    org.apache.cxf.transport.servlet.AbstractHTTPServlet.service(AbstractHTTPServlet.java:262)
    org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)

奇怪的是,这个错误并没有出现在tomcat日志中。

我做了一些研究,似乎这个类是jax-rs的一部分。在我的maven pom中,我已经包含了这种依赖:

    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>javax.ws.rs-api</artifactId>
        <version>2.0.1</version>
    </dependency>

但是这种依赖似乎没有这个类。该类在此依赖项中是

    <dependency>
        <groupId>javax.ws.rs</groupId>
        <artifactId>javax.ws.rs-api</artifactId>
        <version>2.0-m01</version>
    </dependency>

我感到不安的是降级到较低版本,但这是一个里程碑。更重要的是,该jar不包括我在javax.ws.rs.client.ClientBuilder等代码中使用的类。

任何人都可以解释为什么我会收到此例外以及如何解决此问题?


我的解决方法

我得出的结论是,这与Jersey客户端和CXF相互干扰有很大关系。我决定删除Jersey客户端并将其替换为CXF客户端。这些说明比官方指示要好得多:http://fandry.blogspot.com/2012/06/how-to-create-simple-cxf-based-jax-rs.html

import com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider;
import org.apache.cxf.jaxrs.client.WebClient;
import java.util.ArrayList;
import java.util.List;

public class App 
{
    public static void main( String[] args )  throws Exception { 

     List<Object> providers = new ArrayList<Object>();
     providers.add( new JacksonJaxbJsonProvider() );

     WebClient client = WebClient.create("http://localhost:8080/poc_restapi_cxf/api", providers);
     client = client.accept("application/json").type("application/json").path("/order").query("id", "1");

     Order order = client.get(Order.class);
     System.out.println("Order:" + order.getCustomerName());

    }
}

非常相似的API。我只是搜索并替换了一些方法名称,一切正常。

3 个答案:

答案 0 :(得分:2)

我也遇到过这个问题。不像你的项目要求意味着我必须让泽西和CXF打得很好。

最终的问题是在FactoryFinder类中,Jersey使用它来获取适当的运行时委托(用于各种子对象) - 这反过来又有一个类导入到违规类。

要解决这个问题,您需要在资源文件夹中设置一个文件(假设它被导入到您的classpath文件夹中),其路径为META-INF / services / javax.ws.rs.ext.RuntimeDelegate,其中包含以下值:

org.glassfish.jersey.internal.RuntimeDelegateImpl

这可以解决您的问题。

答案 1 :(得分:0)

添加以下Maven依赖

<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0-m08</version>
</dependency>  

答案 2 :(得分:-1)

我有一个非常类似的问题。当我通过添加依赖项(javax.ws.rs)修复异常时,我无法使用javax.ws.rs.client.ClientBuilder。我做了以下改变,问题似乎消失了。

file web.xml

<servlet>
 <servlet-name>Jersey Web Application</servlet-name>
 - <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
 + <servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
 <init-param>
 - <param-name>jersey.config.server.provider.packages</param-name>
 + <param-name>com.sun.jersey.config.property.packages</param-name>
    <param-value>com.test.test1</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
<servlet>