2015-01-09 32 views
5

Sto distribuendo una guerra a Tomcat 7.0.57. Questo codice utilizza il client Jersey 2.x per comunicare con un endpoint Rest e espone i propri endpoint Resto utilizzando CXF (AKA the war's endpoint).java.lang.ClassNotFoundException: javax.ws.rs.MessageProcessingException

Quando ho colpito uno degli endpoint della guerra, il codice sembra funzionare e restituisce una risposta senza problemi dal punto di vista del server, ma il client riceve una risposta 500 da Tomcat. Questo è l'errore:

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) 

Stranamente, questo errore non viene visualizzato nel registro tomcat.

Ho fatto una piccola ricerca e sembra che questa classe sia parte di jax-rs. Nel mio esperto di pom, sto già compreso questa dipendenza:

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

Ma questa dipendenza non sembra avere questa classe. Quella classe è in questa dipendenza però:

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

mi sento a disagio declassamento a una versione più bassa che è una pietra miliare però. Ancora più importante, quel jar non include le classi che sto usando nel mio codice come javax.ws.rs.client.ClientBuilder.

Qualcuno può spiegare perché sto ricevendo questa eccezione e come risolvere questo problema?


mia soluzione

Sono venuto alla conclusione che questo ha più a che fare con il Cliente Jersey e CXF interferire con l'altro. Ho deciso di rimuovere il client Jersey e sostituirlo con il client CXF. Queste istruzioni sono molto meglio di quelli ufficiali: 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()); 

    } 
} 

Molto simile API. Ho appena cercato e sostituito alcuni nomi di metodi e tutto ha funzionato.

+1

@ Michael-O Perché diverse persone guardano ogni –

risposta

3

Mi sono imbattuto anche in questo problema. A differenza dei requisiti del progetto, dovevo far sì che Jersey e CXF giocassero bene.

Il problema finale è nella classe FactoryFinder che viene utilizzata da Jersey per ottenere il delegato di runtime appropriato (utilizzato per vari oggetti sussidiari), che a sua volta ha una classe con un'importazione nella classe all'origine dell'errore.

Per aggirare questo è necessario disporre di un file nella cartella delle risorse (presumendo che questo venga importato nella cartella classpath) con il percorso META-INF/services/javax.ws.rs.ext.RuntimeDelegate che contiene il valore :

org.glassfish.jersey.internal.RuntimeDelegateImpl 

Questo dovrebbe risolvere il problema.

+0

Questo lo ha risolto per me. Grazie. – Rusty

+0

salvato il giorno! come mai hai trovato questa soluzione nel mondo? – spy

0

Add seguente Maven dipendenza

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

"Mi sento a disagio nel passare a una versione inferiore, ma è un traguardo." –

+2

Questa soluzione si limitava a scambiare un problema con un altro. Invece della classe mancante menzionata dall'OP, ora mi manca javax/ws/rs/NotFoundException – Blamkin86

+0

Ottenuto lo stesso errore riportato da @ Blamkin86, java.lang.ClassNotFoundException: javax.ws.rs.NotFoundException –

-1

Ho avuto un problema molto simile. Quando ho risolto l'eccezione aggiungendo dipendenza (javax.ws.rs), non ero in grado di utilizzare javax.ws.rs.client.ClientBuilder. Ho fatto il seguente cambiamento e il problema sembra essere andato.

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>