Anyframe Apache-cxf를 활용한 웹서비스 개발 관련 문의드립니다
Submitted by escalation on 수, 04/21/2010 - 16:11
안녕하세요. 공공IE1그룹 조영일 책임입니다.
3월말에 멀티캠퍼스에서 Anyframe java를 활용한 오픈소스 기반의 개발 교육을 들은 수강생이기도 합니다.
회사에 돌아와서 교육받은 웹서비스를 테스트 해보다가 도저히 해결이 안되는 부분이 있어서
이렇게 문의를 드립니다.
제가 하고 있는 것은 관세청 RFID서버와 동일한 환경으로 구성을 해서 웹서비스를 로컬에서
테스트 해보는 것입니다.
소스나 웹서비스 방식은 Annotation이 아닌 bean.xml방식으로 웹서비스를 올리는 것이죠. 그리고
사용하는 클라이언트도 bean.xml을 이용해서 데이타를 호출하는 것입니다.
쉽게 생각했는데 전송하다보면 AgeisBinding에서 지속적인 오류가 나는 것으로 판단됩니다.
다른 개발자에게도 문의해보니 대부분 초기 컨설팅 받을 때 설정 그래도 사용해서 해결을 못하네요..
그래서 부득이 질문을 드립니다. 저는 아파치 톰캣이 아니라 웹로직 10에서 서비스를 기동하고
있습니다만 제 생각에는 아파치 톰캣에서 돌려도 문제없이 서비스 될거라 판단됩니다.
일단 제가 변경한 소스 전체를 보내드립니다.
그리고 오류내역을 캡쳐한 파일도 보내드립니다.
바쁘시겠지만 제가 뭘 잘못 설정했거나 소스에 누락을 한 것인지 도움 부탁드립니다.
그럼 수고하세요~~


답변입니다.
escalation님,
따로 메일로 보내주신 예제 코드를 Apache Tomcat 서버에서 수행시켜서 아래와 같이 2가지 에러가 발생하는 것을 확인하였습니다.
각각의 에러 사항을 조치한 내역을 설명드리겠습니다.
조치된 결과, 정상적으로 동작하는 예제 코드를 다시 첨부해드렸습니다. (Anyframe-Lab-WebServices-0421.zip)
Weblogic에서 수행시켜보시고 문제 발생 시 다시 문의해주시기 바랍니다.
[1] org.apache.cxf.interceptor.Fault 에러 발생
1.1 상세 에러 메시지
2010. 4. 21 오전 10:39:37 org.apache.cxf.phase.PhaseInterceptorChain doIntercept
정보: Interceptor has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: Could not send Message.
at org.apache.cxf.interceptor.MessageSenderInterceptor$MessageSenderEndingInterceptor.handleMessage(MessageSenderInterceptor.java:64)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:220)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:466)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:299)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:251)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:73)
at org.apache.cxf.frontend.ClientProxy.invoke(ClientProxy.java:68)
at $Proxy31.get(Unknown Source)
at anyframe.lab.webservices.client.web.ProductController.get(ProductController.java:35)
1.2 조치 내역 I
이 예제 코드는 서버 프로젝트 코드와 클라이언트 프로젝트 코드로 구분되어 있는데,
서버 프로젝트 코드의 ProductService(인터페이스 클래스)와 Product(도메인 클래스) 클래스를
클라이언트 프로젝트 코드에 가져온 후, 기존에 클라이언트 프로젝트에 있던 ProductService,Product 클래스를 제거한다.
즉, anyframe-lab-webservices-client 프로젝트에서 아래 2개 클래스를 제거하고,
anyframe.lab.webservices.client.domain 패키지 하위 Product.java
anyframe.lab.webservices.client.service 패키지 하위 ProductService.java
아래 2개 클래스를 추가해넣는다.
anyframe.lab.webservices.server.domain 패키지 하위 Product.java
anyframe.lab.webservices.server.service 패키지 하위 ProductService.java
ProductController.java 내 Product, ProductService에 대한 패키지 정보 수정한다.
이유: 서버와 클라이언트 모두 동일한 인터페이스 클래스와 도메인 클래스를 사용하기 위함
1.3 조치 내역 II
anyframe-lab-webservices-client\src\main\resources\springmvc\common-servlet.xml 파일에서 아래와 같이 serviceClass 명을 변경시킨다.
>simple:client id="productService" serviceClass="anyframe.lab.webservices.server.service.ProductService"
address="http://localhost:8080/anyframe-lab-webservices-server/ws/ProductService">
>simple:dataBinding>
>bean class="org.apache.cxf.aegis.databinding.AegisDatabinding" />
>/simple:dataBinding>
>/simple:client>
[2] Failed to invoke last-modified method 에러 발생
2.1 상세 에러 메시지
2010-04-21 10:06:16,868 ERROR [anyframe.lab.webservices.client.web.ProductController] Failed to invoke last-modified method
java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedMethodAccessor22.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.getLastModified(MultiActionController.java:377)
.
.
.
.
.
Caused by: java.lang.StackOverflowError
at java.util.HashMap.put(HashMap.java:425)
at java.util.HashSet.add(HashSet.java:194)
at java.lang.ClassLoader.checkPackageAccess(ClassLoader.java:336)
at org.apache.log4j.spi.LoggingEvent.(LoggingEvent.java:159)
at org.apache.log4j.Category.forcedLog(Category.java:391)
at org.apache.log4j.Category.log(Category.java:856)
at org.apache.commons.logging.impl.Log4JLogger.error(Log4JLogger.java:257)
at org.springframework.web.servlet.mvc.multiaction.MultiActionController.getLastModified(MultiActionController.java:383)
2.2 조치 내역
ProductController 클래스의 기존의 get 메소드명을 getProduct로 변경하였습니다.
만약 Controller 클래스에 get 메소드 명을 반드시 써야 한다면, 아래와 같이 getLastModified 메소드를 오버라이드해주셔야 합니다.
그 이유는, 이 Controller 클래스가 MultiActionController 클래스를 상속받았기 때문에 get이라는 method로 설정하게되면
내부적으로 '재귀적 호출'이 발생하게 되어 결국에는 'Failed to invoke last-modified method'라는 에러 메시지가 발생하게 됩니다.
ProductController.java 내부에 아래 메소드 추가하시면 됩니다.
@Override
public long getLastModified(HttpServletRequest request) {
return -1;
}
[3] 권고사항
Simple Frontend 방식보다 JAX-WS Frontend 방식을 추천합니다.
표준 방식인 JAX-WS, JAXB Databinding을 사용하기 때문입니다.
감사합니다.