7 Replies Latest reply on Jan 9, 2008 10:28 AM by Richard Opalka

    SoapFault on returning the web service response

    Gary Greenberg Newbie

      I have created a simple JAX-WS web service to process spam complaints
      Here is the Java code of it:

      @WebService(targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0")
      public class SpamComplaintWS
      {
       @WebMethod(operationName="processSpamComplaints")
       @WebResult(name="SpamResult")
       @ResponseWrapper(className="com.rsys.rsystools.ws.SpamResult")
       public SpamResult processSpamComplaints(
       @WebParam(name = "email") String email,
       @WebParam(name = "fromAddress") String fromAddress,
       @WebParam(name = "mailDate") String mailDate,
       @WebParam(name = "complaintDate") String complaintDate,
       @WebParam(name = "mailbox") String mailbox,
       @WebParam(name = "complainer") String complainer,
       @WebParam(name = "xRext") String xRext,
       @WebParam(name = "accountName") String accountName)
       {
       responsys.prodtools.SpammerTables st = new responsys.prodtools.SpammerTables();
       String[] res = st.processSpamRecord(email, fromAddress, mailDate, complaintDate, mailbox, complainer, xRext, accountName);
       return (new SpamResult(res[0],res[1],res[2],res[3],res[4],res[5],res[6],res[7],res[8],res[9],res[10],res[11],res[12],res[13]));
       }
      }
      

      It compiles and deploys successfully, however, generated wsdl is not what I expected to see:
      - <definitions name="SpamComplaintWSService" targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      - <types>
      - <xs:schema targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0" version="1.0" xmlns:tns="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
       <xs:element name="processSpamComplaints" type="tns:processSpamComplaints" />
       <xs:element name="processSpamComplaintsResponse" type="tns:processSpamComplaintsResponse" />
      - <xs:complexType name="processSpamComplaints">
      - <xs:sequence>
       <xs:element minOccurs="0" name="email" type="xs:string" />
       <xs:element minOccurs="0" name="fromAddress" type="xs:string" />
       <xs:element minOccurs="0" name="mailDate" type="xs:string" />
       <xs:element minOccurs="0" name="complaintDate" type="xs:string" />
       <xs:element minOccurs="0" name="mailbox" type="xs:string" />
       <xs:element minOccurs="0" name="complainer" type="xs:string" />
       <xs:element minOccurs="0" name="xRext" type="xs:string" />
       <xs:element minOccurs="0" name="accountName" type="xs:string" />
       </xs:sequence>
       </xs:complexType>
      - <xs:complexType name="processSpamComplaintsResponse">
      - <xs:sequence>
       <xs:element minOccurs="0" name="SpamResult" type="tns:processSpamComplaintsResponse" />
       </xs:sequence>
       </xs:complexType>
       </xs:schema>
       </types>
      - <message name="SpamComplaintWS_processSpamComplaints">
       <part element="tns:processSpamComplaints" name="processSpamComplaints" />
       </message>
      - <message name="SpamComplaintWS_processSpamComplaintsResponse">
       <part element="tns:processSpamComplaintsResponse" name="processSpamComplaintsResponse" />
       </message>
      - <portType name="SpamComplaintWS">
      - <operation name="processSpamComplaints" parameterOrder="processSpamComplaints">
       <input message="tns:SpamComplaintWS_processSpamComplaints" />
       <output message="tns:SpamComplaintWS_processSpamComplaintsResponse" />
       </operation>
       </portType>
      - <binding name="SpamComplaintWSBinding" type="tns:SpamComplaintWS">
       <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
      - <operation name="processSpamComplaints">
       <soap:operation soapAction="" />
      - <input>
       <soap:body use="literal" />
       </input>
      - <output>
       <soap:body use="literal" />
       </output>
       </operation>
       </binding>
      - <service name="SpamComplaintWSService">
      - <port binding="tns:SpamComplaintWSBinding" name="SpamComplaintWSPort">
       <soap:address location="http://127.0.0.1:80/RsysTools/ws/SpamComplaintWS" />
       </port>
       </service>
       </definitions>
      

      (It is copied from the browser, so, don't mind dashes).
      As you can see, I explicitly stated the name and class for my return value but wsdl ignores that part. I mean @WebResult and @ResponceWrapper annotations.
      I can call the web service in it successfully performs its job (I know it by the results of the database transaction) by I still getting an exception on result return:
      javax.xml.ws.soap.SOAPFaultException: java.lang.reflect.UndeclaredThrowableException
       at com.sun.xml.ws.fault.SOAP11Fault.getProtocolException(SOAP11Fault.java:171)
       at com.sun.xml.ws.fault.SOAPFaultBuilder.createException(SOAPFaultBuilder.java:94)
       at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:240)
       at com.sun.xml.ws.client.sei.SyncMethodHandler.invoke(SyncMethodHandler.java:210)
       at com.sun.xml.ws.client.sei.SEIStub.invoke(SEIStub.java:103)
       at $Proxy29.processSpamComplaints(Unknown Source)
       at com.rsys.rsystools.client.SpamComplainClient.doComplain(SpamComplainClient.java:409)
      

      Can someone tells me what is wrong with my code and how to make it work.
      I am doing it on JBoss 4.2.1 with the JBossWS 2.0.1GA
      Thanks.

        • 1. Re: SoapFault on returning the web service response
          Gary Greenberg Newbie

          I made a little change in the service and instead of class instance returning an array of java.lang.String.
          In this case service works without complaints. So, it is definitely a bug in the @ResponseWrapper conversion.
          Can anyone verify it for me please?

          • 2. Re: SoapFault on returning the web service response
            Richard Opalka Newbie

            Try to specify

            @WebResult
            (
             name="SpamResult",
             targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0"
            )
            @RequestWrapper
            (
             localName="Spam",
             targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0",
             className = "com.rsys.rsystools.ws.Spam"
            )
            @ResponseWrapper(
             name="SpamResult",
             targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0",
             className = "com.rsys.rsystools.ws.SpamResult"
            )
            public SpamResult processSpamComplaints(...)
            {
            ...
            }


            You're working with wrapped literal, so don't forget to provide RequestWrapper too.

            Richard

            • 3. Re: SoapFault on returning the web service response
              Gary Greenberg Newbie

              So, you think that namespace is the solution to the problem?
              I am sure that you are wrong. I did try your suggestion but it did not work.
              I made this change:

              @WebMethod(operationName="processSpamComplaints")
               @WebResult(name="spamResult",targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0")
               @ResponseWrapper(localName="result",className="com.rsys.rsystools.ws.SpamResult",
               targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0")
               public SpamResult processSpamComplaints(
              

              I did not create RequestWrapper because
              a)I am not passing in an instance of class but just few strings.
              b)passed in parameters are processed correctly.
              So, when I redeployed my service generated wsdl looked like:
              <definitions name="SpamComplaintWSService" targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0">
              ?
               <types>
              ?
               <xs:schema targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0" version="1.0">
              <xs:element name="processSpamComplaints" type="tns:processSpamComplaints"/>
              <xs:element name="result" type="tns:result"/>
              ?
               <xs:complexType name="processSpamComplaints">
              ?
               <xs:sequence>
              <xs:element minOccurs="0" name="email" type="xs:string"/>
              <xs:element minOccurs="0" name="fromAddress" type="xs:string"/>
              <xs:element minOccurs="0" name="mailDate" type="xs:string"/>
              <xs:element minOccurs="0" name="complaintDate" type="xs:string"/>
              <xs:element minOccurs="0" name="mailbox" type="xs:string"/>
              <xs:element minOccurs="0" name="complainer" type="xs:string"/>
              <xs:element minOccurs="0" name="xRext" type="xs:string"/>
              <xs:element minOccurs="0" name="accountName" type="xs:string"/>
              </xs:sequence>
              </xs:complexType>
              ?
               <xs:complexType name="result">
              ?
               <xs:sequence>
              <xs:element form="qualified" minOccurs="0" name="spamResult" type="tns:result"/>
              </xs:sequence>
              </xs:complexType>
              </xs:schema>
              </types>
              ?
               <message name="SpamComplaintWS_processSpamComplaints">
              <part element="tns:processSpamComplaints" name="processSpamComplaints"/>
              </message>
              ?
               <message name="SpamComplaintWS_processSpamComplaintsResponse">
              <part element="tns:result" name="result"/>
              </message>
              ?
               <portType name="SpamComplaintWS">
              ?
               <operation name="processSpamComplaints" parameterOrder="processSpamComplaints">
              <input message="tns:SpamComplaintWS_processSpamComplaints"/>
              <output message="tns:SpamComplaintWS_processSpamComplaintsResponse"/>
              </operation>
              </portType>
              ?
               <binding name="SpamComplaintWSBinding" type="tns:SpamComplaintWS">
              <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
              ?
               <operation name="processSpamComplaints">
              <soap:operation soapAction=""/>
              ?
               <input>
              <soap:body use="literal"/>
              </input>
              ?
               <output>
              <soap:body use="literal"/>
              </output>
              </operation>
              </binding>
              ?
               <service name="SpamComplaintWSService">
              ?
               <port binding="tns:SpamComplaintWSBinding" name="SpamComplaintWSPort">
              <soap:address location="http://127.0.0.1:80/rsystools/ws/SpamComplaintWS"/>
              </port>
              </service>
              </definitions>

              and when I called the web service, the result was exactly like in my original post.

              • 4. Re: SoapFault on returning the web service response
                Gary Greenberg Newbie

                I kept experimenting with this service and when I commented out @ResponseWrapper annotation it started generating correct wsdl.

                Now I am confident that there is a bug in JBossWS

                • 5. Re: SoapFault on returning the web service response
                  Richard Opalka Master

                  Hi,

                  I followed your usecase and here are the source codes I created:

                  package org.jboss.test.ws.jaxws.jbws1845;
                  
                  import javax.ejb.Stateless;
                  import javax.jws.WebMethod;
                  import javax.jws.WebParam;
                  import javax.jws.WebResult;
                  import javax.jws.WebService;
                  import javax.xml.ws.ResponseWrapper;
                  
                  import org.jboss.wsf.spi.annotation.WebContext;
                  
                  @Stateless
                  @WebService
                  (
                   targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0",
                   serviceName="SpamService"
                  )
                  @WebContext
                  (
                   transportGuarantee="NONE",
                   contextRoot="/jaxws-jbws1845",
                   urlPattern="/SpamService"
                  )
                  public final class SpamComplaintWS implements SpamComplaintWSIface
                  {
                   @WebMethod(operationName="processSpamComplaints")
                   @WebResult(name="SpamResult")
                   @ResponseWrapper(className="org.jboss.test.ws.jaxws.jbws1845.jaxws.SpamResult")
                   public SpamResult processSpamComplaints(
                   @WebParam(name = "email") String email,
                   @WebParam(name = "fromAddress") String fromAddress,
                   @WebParam(name = "mailDate") String mailDate,
                   @WebParam(name = "complaintDate") String complaintDate,
                   @WebParam(name = "mailbox") String mailbox,
                   @WebParam(name = "complainer") String complainer,
                   @WebParam(name = "xRext") String xRext,
                   @WebParam(name = "accountName") String accountName)
                   {
                   return new SpamResult(email, fromAddress, mailDate, complaintDate, mailbox, complainer, xRext, accountName);
                   }
                  }
                  


                  package org.jboss.test.ws.jaxws.jbws1845;
                  
                  import javax.ejb.Remote;
                  import javax.jws.WebMethod;
                  import javax.jws.WebParam;
                  import javax.jws.WebResult;
                  import javax.jws.WebService;
                  import javax.xml.ws.ResponseWrapper;
                  
                  @Remote
                  @WebService
                  public interface SpamComplaintWSIface
                  {
                   @WebMethod(operationName="processSpamComplaints")
                   @WebResult(name="SpamResult")
                   @ResponseWrapper(className="org.jboss.test.ws.jaxws.jbws1845.jaxws.SpamResult")
                   public SpamResult processSpamComplaints(
                   @WebParam(name = "email") String email,
                   @WebParam(name = "fromAddress") String fromAddress,
                   @WebParam(name = "mailDate") String mailDate,
                   @WebParam(name = "complaintDate") String complaintDate,
                   @WebParam(name = "mailbox") String mailbox,
                   @WebParam(name = "complainer") String complainer,
                   @WebParam(name = "xRext") String xRext,
                   @WebParam(name = "accountName") String accountName
                   );
                  }
                  


                  package org.jboss.test.ws.jaxws.jbws1845;
                  
                  import javax.xml.bind.annotation.XmlAccessType;
                  import javax.xml.bind.annotation.XmlAccessorType;
                  import javax.xml.bind.annotation.XmlElement;
                  import javax.xml.bind.annotation.XmlType;
                  
                  @XmlAccessorType(XmlAccessType.FIELD)
                  @XmlType(name = "SpamResult", propOrder = {
                   "email",
                   "fromAddress",
                   "mailDate",
                   "complaintDate",
                   "mailbox",
                   "complainer",
                   "xRext",
                   "accountName"
                  })
                  public final class SpamResult
                  {
                   @XmlElement(required = true, nillable = true)
                   protected String email;
                   @XmlElement(required = true, nillable = true)
                   protected String fromAddress;
                   @XmlElement(required = true, nillable = true)
                   protected String mailDate;
                   @XmlElement(required = true, nillable = true)
                   protected String complaintDate;
                   @XmlElement(required = true, nillable = true)
                   protected String mailbox;
                   @XmlElement(required = true, nillable = true)
                   protected String complainer;
                   @XmlElement(required = true, nillable = true)
                   protected String xRext;
                   @XmlElement(required = true, nillable = true)
                   protected String accountName;
                  
                   public SpamResult()
                   {
                   }
                  
                   public SpamResult(String email, String fromAddress, String mailDate, String complaintDate, String mailbox, String complainer, String xRext, String accountName)
                   {
                   this.email = email;
                   this.fromAddress = fromAddress;
                   this.mailDate = mailDate;
                   this.complaintDate = complaintDate;
                   this.mailbox = mailbox;
                   this.complainer = complainer;
                   this.xRext = xRext;
                   this.accountName = accountName;
                   }
                  
                   public String[] get()
                   {
                   return new String[] { email, fromAddress, mailDate, complaintDate, mailbox, complainer, xRext, accountName };
                   }
                  }
                  


                  package org.jboss.test.ws.jaxws.jbws1845;
                  
                  import java.net.URL;
                  import javax.xml.namespace.QName;
                  import javax.xml.ws.Service;
                  import junit.framework.Test;
                  import org.jboss.wsf.test.JBossWSTest;
                  import org.jboss.wsf.test.JBossWSTestSetup;
                  
                  public final class JBWS1845TestCase extends JBossWSTest
                  {
                   public static Test suite()
                   {
                   return new JBossWSTestSetup(JBWS1845TestCase.class, "jaxws-jbws1845.jar");
                   }
                  
                   public void testIssue() throws Exception
                   {
                   QName serviceName = new QName("http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0", "SpamService");
                   URL wsdlURL = new URL("http://" + getServerHost() + ":8080/jaxws-jbws1845/SpamService?wsdl");
                  
                   Service service = Service.create(wsdlURL, serviceName);
                   SpamComplaintWSIface proxy = (SpamComplaintWSIface)service.getPort(SpamComplaintWSIface.class);
                  
                   String[] orig = { "email", "fromAddress", "mailDate", "complaintDate", "mailbox", "complainer", "xRext", "accountName"};
                   String[] returned = proxy.processSpamComplaints(orig[0], orig[1], orig[2], orig[3], orig[4], orig[5], orig[6], orig[7]).get();
                   for (int i = 0; i < orig.length; i++)
                   {
                   assertEquals(orig, returned);
                   }
                   }
                  
                  }
                  


                  • 6. Re: SoapFault on returning the web service response
                    Richard Opalka Master

                    This is the generated WSDL

                    <definitions name="SpamService" targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tns="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                     <types>
                     <xs:schema targetNamespace="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0" version="1.0" xmlns:tns="http://service.responsys.com/rsystools/ws/SpamComplaintWS/1.0" xmlns:xs="http://www.w3.org/2001/XMLSchema">
                     <xs:element name="processSpamComplaints" type="tns:processSpamComplaints"/>
                     <xs:element name="processSpamComplaintsResponse" type="tns:processSpamComplaintsResponse"/>
                     <xs:complexType name="processSpamComplaints">
                     <xs:sequence>
                     <xs:element minOccurs="0" name="email" type="xs:string"/>
                     <xs:element minOccurs="0" name="fromAddress" type="xs:string"/>
                     <xs:element minOccurs="0" name="mailDate" type="xs:string"/>
                     <xs:element minOccurs="0" name="complaintDate" type="xs:string"/>
                     <xs:element minOccurs="0" name="mailbox" type="xs:string"/>
                     <xs:element minOccurs="0" name="complainer" type="xs:string"/>
                     <xs:element minOccurs="0" name="xRext" type="xs:string"/>
                     <xs:element minOccurs="0" name="accountName" type="xs:string"/>
                     </xs:sequence>
                     </xs:complexType>
                     <xs:complexType name="processSpamComplaintsResponse">
                     <xs:sequence>
                     <xs:element minOccurs="0" name="SpamResult" type="tns:SpamResult"/>
                     </xs:sequence>
                     </xs:complexType>
                     <xs:complexType final="extension restriction" name="SpamResult">
                     <xs:sequence>
                     <xs:element name="email" nillable="true" type="xs:string"/>
                     <xs:element name="fromAddress" nillable="true" type="xs:string"/>
                     <xs:element name="mailDate" nillable="true" type="xs:string"/>
                     <xs:element name="complaintDate" nillable="true" type="xs:string"/>
                     <xs:element name="mailbox" nillable="true" type="xs:string"/>
                     <xs:element name="complainer" nillable="true" type="xs:string"/>
                     <xs:element name="xRext" nillable="true" type="xs:string"/>
                     <xs:element name="accountName" nillable="true" type="xs:string"/>
                     </xs:sequence>
                     </xs:complexType>
                     </xs:schema>
                     </types>
                     <message name="SpamComplaintWS_processSpamComplaints">
                     <part element="tns:processSpamComplaints" name="processSpamComplaints"/>
                     </message>
                     <message name="SpamComplaintWS_processSpamComplaintsResponse">
                     <part element="tns:processSpamComplaintsResponse" name="processSpamComplaintsResponse"/>
                     </message>
                     <portType name="SpamComplaintWS">
                     <operation name="processSpamComplaints" parameterOrder="processSpamComplaints">
                     <input message="tns:SpamComplaintWS_processSpamComplaints"/>
                     <output message="tns:SpamComplaintWS_processSpamComplaintsResponse"/>
                     </operation>
                     </portType>
                     <binding name="SpamComplaintWSBinding" type="tns:SpamComplaintWS">
                     <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http"/>
                     <operation name="processSpamComplaints">
                     <soap:operation soapAction=""/>
                     <input>
                     <soap:body use="literal"/>
                     </input>
                     <output>
                     <soap:body use="literal"/>
                     </output>
                     </operation>
                     </binding>
                     <service name="SpamService">
                     <port binding="tns:SpamComplaintWSBinding" name="SpamComplaintWSPort">
                     <soap:address location="http://localhost.localdomain:8080/jaxws-jbws1845/SpamService"/>
                     </port>
                     </service>
                    </definitions>


                    • 7. Re: SoapFault on returning the web service response
                      Richard Opalka Master

                       

                      "ggary" wrote:
                      I kept experimenting with this service and when I commented out @ResponseWrapper annotation it started generating correct wsdl.

                      Now I am confident that there is a bug in JBossWS


                      I don't think so. Here are some points you should know:

                      * there's almost always no reason to use @ResponseWrapper(className="package.ClassName") on your methods
                      because this annotation parameter defines the runtime generated wrapper bean name you as user will never see and deal with
                      * one possible reason to use this annotation parameter is e.g. http://jbws.dyndns.org/mediawiki/index.php?title=FAQ#Why_I.27m_getting_.22propertyname_is_not_valid_property_on_class_mypackage.jaxws.Propertyname.22.3F
                      * for further information take a look to JAX-WS specification where you can find more information about @RequestWrapper and @ResponseWrapper annotations

                      Back to your problem.
                      * you can omit @ResponseWrapper(className="xyz") definition, it's not necessary
                      * ensure your SpamResult class is JAXB well annotated (see my example above)
                      so it can be de/serialized by JAXB runtime