본문 바로가기
IBM - old/WAS 문제&해결

JAX-WS 기반의 Web service 개발시에 varargs 나 List<Object> 사용해서 call 을 수행시 Exception

by freeman98 2016. 5. 30.

1. WAS 버전 : WAS v7.0 이상


2. OS : All


3. Error 발생 시점 : JAX-WS 기반의 Web service 개발시에 varargs 나 List<Object> 사용해서 call 을 수행하면 javax.xml.ws.soap.SOAPFaultException: org.apache.xerces.dom.ElementNSImpl incompatible exception
(int 와 같은 primitive type 은 정상 동작)


4. Error message :
[ERROR   ] SRVE0777E: 애플리케이션 클래스 'org.apache.cxf.jaxws.JaxWsClientProxy.invoke:156'에서 발생한 예외
javax.xml.ws.soap.SOAPFaultException: org.apache.xerces.dom.ElementNSImpl incompatible with com.ibm.juwlee.jaxws.TestVO
    at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:156)
    at [internal classes]
    at com.sun.proxy.$Proxy185.callIt(Unknown Source)
    at com.ibm.juwlee.servlet.VarargsCall.doWork(VarargsCall.java:75)
    at com.ibm.juwlee.servlet.VarargsCall.doGet(VarargsCall.java:40)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:575)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
    at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1274)
    at [internal classes]
Caused by: org.apache.cxf.binding.soap.SoapFault: org.apache.xerces.dom.ElementNSImpl incompatible with com.ibm.juwlee.jaxws.TestVO
    at org.apache.cxf.binding.soap.interceptor.Soap11FaultInInterceptor.unmarshalFault(Soap11FaultInInterceptor.java:84)
    ... 8 more


5. 예상 이유 :  JAX-WS 에서 사용하는 JAXB 표준에 의해서 varargs 나 List<Object> 를 전달할 경우 그 안에서 별도로 사용된 custom object 를 web service 로 보내기 위해서 marshal 이 수행되는데 이 때 해당 custom object 의 정보가 정확하게 명시되지 않아서 잘못된 중간 객체인 org.apache.xerces.dom.ElementNSImpl 형태로 그냥 server 로 보내서 server 단에서 unmarshal 관련 이슈 발생


6. 조치 방안 :  JAX-WS 에서 사용하는 JAXB 표준에 의해서 @XmlSeeAlso annotation 을 추가하여 custom object 의 정보를 같이 JAXB class 로 생성할 수 있도록 해주면 됨(WSDL, client 재생성 필요)


7. 참고 자료  


import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.xml.bind.annotation.XmlSeeAlso;

@WebService(serviceName = "VarargsJAXWSCallService")
@XmlSeeAlso({com.ibm.juwlee.jaxws.TestVO.class})
public class VarargsJAXWSCall implements VarargsJAXWSInterface{
  
    @WebMethod
    public Object CallIt(Object...objects) {
        int sum = 0;
      
        for (Object o:objects){
            System.out.println("Obj = " + o);
            try {
                sum += (int)o;
            }catch(ClassCastException e) {
                int aaa = ((TestVO)o).getA();
                System.out.println("AAA = " + aaa);
                sum += aaa;
            }
        }
        System.out.println("Sum = " + sum);
        return sum;
    }

}

댓글