2015-01-09 1 views
5

Tomcat 7.0.57에 war를 배포하고 있습니다. 이 코드는 Jersey 2.x Client를 사용하여 Rest 엔드 포인트와 통신하고 CXF (일명 엔드 포인트)를 사용하여 자체 Rest 엔드 포인트를 표시합니다.java.lang.ClassNotFoundException : javax.ws.rs.MessageProcessingException

전쟁의 끝점 중 하나에 충돌했을 때 코드는 작동하는 것처럼 보이고 서버의 관점에서 문제없이 응답을 반환하지만 클라이언트는 500 개의 응답을 Tomcat에서 반환합니다. 이것은 오류입니다 :

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의 일부인 것처럼 보입니다.

<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> 

내가 비록 이정표 낮은 버전에 불편 다운 그레이드를 느낀다. 더 중요한 것은, 해당 항아리에는 javax.ws.rs.client.ClientBuilder과 같은 코드에서 사용하는 클래스가 포함되지 않는다는 것입니다.

아무도 왜이 예외가 발생하는지 그리고이 문제를 해결하는 방법을 설명 할 수 있습니까?


내 해결

나는이 저지 클라이언트와 CXF가 서로 간섭과 더 가지고 있다는 결론에 도달했습니다. Jersey Client를 제거하고 CXF Client로 교체하기로 결정했습니다. 이 지침은 공식 것보다 훨씬 더 있습니다 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. 방금 몇 가지 메소드 이름을 검색하고 바꿨고 모든 것이 작동했습니다.

+1

@ Michael-O 각기 다른 사람들이 각기 다르기 때문에 –

답변

3

나는이 문제에 대해서도 역시 알았다. 프로젝트 요구 사항과 달리 Jersey와 CXF를 훌륭하게 연주해야했습니다.

궁극적 인 문제는 저지가 적절한 보조 런타임 객체 (다양한 보조 객체에 사용됨)를 얻기 위해 Jersey에서 사용하는 FactoryFinder 클래스에 있습니다.이 클래스는 기분 나쁜 클래스로 가져 오는 클래스를 갖습니다.

이 문제를 해결하려면 리소스 폴더에 값이 들어있는 META-INF/services/javax.ws.rs.ext.RuntimeDelegate 경로가있는 파일이 있어야합니다 (클래스 경로 폴더로 가져 오는 것으로 가정). :

org.glassfish.jersey.internal.RuntimeDelegateImpl 

이렇게하면 문제가 해결됩니다. 메이븐 의존성

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

이 부분이 수정되었습니다. 감사. – Rusty

+0

오늘을 구 했어요! 어떻게이 솔루션을 찾았습니까? – spy

0

추가 나는 매우 비슷한 문제가 있었다. 종속성 (javax.ws.rs)을 추가하여 예외를 수정하면 javax.ws.rs.client.ClientBuilder를 사용할 수 없었습니다. 나는 다음과 같은 변화를 만들었고 문제는 사라진 것처럼 보인다.

파일 웹.xxx

<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> 
+0

"나는 이정표 인 낮은 버전으로 다운 그레이드하는 것을 불편하게 느낀다." –

+2

이 솔루션은 단지 하나의 문제를 다른 것만 교환했습니다. OP가 언급 한 누락 된 클래스 대신, 지금 javax/ws/rs/NotFoundException이 누락되었습니다. – Blamkin86

+0

@ Blamkin86, java.lang.ClassNotFoundException에 의해보고 된 동일한 오류가 발생했습니다 : javax.ws.rs.NotFoundException –