java.lang.ClassNotFoundException: javax.ws.rs.MessageProcessingException
Asked Answered
S

3

7

I am deploying a war to Tomcat 7.0.57. This code uses Jersey 2.x Client to communicate with a Rest endpoint and exposes its own Rest endpoints using CXF (AKA the war's endpoint).

When I hit one of the war's endpoints, the code seems to work and returns a response without issue from the server's perspective, but the client gets a 500 response returned to it from tomcat. This is the error:

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)

Oddly enough, this error doesn't show up in the tomcat log.

I did a little research and it seems that this class is part of jax-rs. In my maven pom, I'm already including this dependency:

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

But this dependency doesn't seem to have this class. That class is in this dependency though:

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

I feel uncomfortable downgrading to a lower version that's a milestone though. More importantly, that jar does not include classes I'm using in my code like javax.ws.rs.client.ClientBuilder.

Can anyone explain why I'm getting this exception and how to resolve this issue?


My Workaround

I've come to the conclusion that this has more to do with the Jersey Client and CXF interfering with each other. I decided to remove the Jersey Client and replace it with the CXF Client. These instructions are much better than the official ones: 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());

    }
}

Very similar API. I just searched and replaced some method names and everything worked.

Swing answered 9/1, 2015 at 20:44 Comment(1)
@Michael-O Because different people look at eachSwing
T
2

I came across this issue too. Unlike you project requirements meant I had to get Jersey and CXF playing nice.

The ultimate problem is in the FactoryFinder class which is used by Jersey to get the appropriate runtime delegate (used for various subsidiary objects) - this in turn has a class with an import to the offending class.

To get around this you need to have a file in your resource folder (presuming this gets imported to your classpath folder) with the path META-INF/services/javax.ws.rs.ext.RuntimeDelegate that contains the value:

org.glassfish.jersey.internal.RuntimeDelegateImpl

This should solve your issue.

Tendency answered 3/2, 2015 at 17:33 Comment(2)
This fixed it for me. Thanks.Remaremain
saved the day! how in the world did you find this solution?Ironwood
R
1

Add following Maven dependency

<dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>javax.ws.rs-api</artifactId>
<version>2.0-m08</version>
</dependency>  
Reglet answered 8/3, 2015 at 8:31 Comment(3)
"I feel uncomfortable downgrading to a lower version that's a milestone though."Swing
This solution merely traded one problem for another. Instead of the missing class mentioned by the OP, I am now missing javax/ws/rs/NotFoundExceptionAmphibiotic
Got the same error reported by @Amphibiotic , java.lang.ClassNotFoundException: javax.ws.rs.NotFoundExceptionSwenson
L
-1

I had a very similar problem. When I fixed the exception by adding dependency (javax.ws.rs), I was then unable to use javax.ws.rs.client.ClientBuilder. I made the following change and the problem seems to be gone.

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>
Landri answered 18/11, 2015 at 10:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.