5

When i call one of the WSDL operation from a spring project, i am getting following exception - com.sun.istack.internal.SAXException2: unable to marshal type "com.pkg.wsdl.ABC" as an element because it is missing an @XmlRootElement annotation

I am using following in pom.xml to generate java objects from a WSDL(already used by many clients) as part of a spring project -

        <groupId>org.jvnet.jaxb2.maven2</groupId>
        <artifactId>maven-jaxb2-plugin</artifactId>
        <version>0.13.1</version>

Looking at similar issue resolution i changed the code to use JAXBElement but still getting same error -

    ABC vabc = new ABC();
    vabc.set(..)   // populate vabc object 

    ObjectFactory of = new ObjectFactory();
    JAXBElement<ABC> jabc = of.createABC(vabc);
    ABC oabc = jabc .getValue();

Marshaller Code -

Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.pkg.wsdl");

and Calling the backend Web Service -

        ABCResp response = (ABCResp) getWebServiceTemplate()
        .marshalSendAndReceive("http://host:port/svcname",oabc);
chappalprasad
  • 775
  • 4
  • 15
  • 26

1 Answers1

7

Had following issues that i had to solve -
1- missing xmlRootElement annotation error
had to pass JAXBElement itself in marshalSendAndReceive as shown below.
You can pull the exact details from ObjectFactory for a QName.

2- missing soapAction in the request error
had to pass WebServiceMessageCallback function as shown below to set soapAction

3- classCastExcetion unmarshalling the response
had to add JAXBIntrospector to fix this error

ABCResp response = (ABCResp ) JAXBIntrospector.getValue(getWebServiceTemplate()
        .marshalSendAndReceive(
                "http://host:port/svcname",
                new JAXBElement<ABC>(new QName(uri, localpart),ABC.class,request),
                new WebServiceMessageCallback() {

                    public void doWithMessage(WebServiceMessage message) {
                        ((SoapMessage)message).setSoapAction("/test");
                    }
                }));        
chappalprasad
  • 775
  • 4
  • 15
  • 26
  • 2
    Perhaps it's a better idea to use methods in ObjectFactory class instead of using `new JAXBElement(new QName(uri, localpart),ABC.class,request)`, this way you don't tight your code with schemas namespaces and URIs if changed. Something like this: `ObjectFactory of = new ObjectFactory(); ABC vabc = of.createABC(); **populate vabc object** and then JAXBElement jabc = of.createABC(vabc);` – Jose-Rdz Jul 06 '17 at 16:07