4 Replies Latest reply on Feb 12, 2005 10:47 AM by thomas.diesler

    web service with document literal and complex types

    andy_wagg

      Does JBoss support this as I am having difficulty figuring this out and making it work. I have a supplied wsdl file that I cannot change. This has methods with complex types.

      I was generating the server side from the wsdl, this was generating a SEI for the methods with multiple parameters. Looking at the Axis debug I was getting an error about differing number of parameters. Looking at the deployed wsdd it seems it operation only has a single parameter, and from googling and reading the WIKI I get the impression that this is all thats allowed.

      I changed my wscompile option to include the -f:wsi option, that now generates me a SEI with a single parameter.Having deployed this, I now get errors about not being able to convert the param classes.

      2005-02-03 08:48:55,239 DEBUG [org.apache.axis.description.ServiceDesc] Enter: syncOperationToClass org.apache.axis.description.Oper
      ationDesc
      name: getStatus
      returnQName: null
      returnType: null
      returnClass: null
      elementQName:{http://opcfoundation.org/webservices/XMLDA/1.0/}GetStatus
      soapAction: null
      style: document
      use: literal
      numInParams: 1
      method:null
       ParameterDesc[0]:
       name: {http://opcfoundation.org/webservices/XMLDA/1.0/}GetStatusResponse
       typeEntry: null
       mode: INOUT
       isReturn: false
       typeQName: {http://opcfoundation.org/webservices/XMLDA/1.0/}GetStatusResponse
       javaType: null
       inHeader: false
       outHeader: false
      
      
      2005-02-03 08:48:55,239 DEBUG [org.apache.axis.description.ServiceDesc] Sync method: public abstract org.opcfoundation.webservices.X
      MLDA._1_0.GetStatusResponse org.opcfoundation.webservices.XMLDA._1_0.Service.getStatus(org.opcfoundation.webservices.XMLDA._1_0.GetS
      tatus) throws java.rmi.RemoteException
      2005-02-03 08:48:55,240 DEBUG [org.apache.axis.description.ServiceDesc] Converting param: class org.opcfoundation.webservices.XMLDA.
      _1_0.GetStatus
      2005-02-03 08:48:55,241 DEBUG [org.apache.axis.description.ServiceDesc] Setting param class from TypeQName: class org.opcfoundation.
      webservices.XMLDA._1_0.GetStatusResponse
      2005-02-03 08:48:55,245 DEBUG [org.apache.axis.utils.JavaUtils] Not convertible: [src=class org.opcfoundation.webservices.XMLDA._1_0
      .GetStatusResponse,dest=class org.opcfoundation.webservices.XMLDA._1_0.GetStatus]
      2005-02-03 08:48:55,245 DEBUG [org.apache.axis.description.ServiceDesc] Param class is not convertible: [param=class org.opcfoundati
      on.webservices.XMLDA._1_0.GetStatusResponse,actual=class org.opcfoundation.webservices.XMLDA._1_0.GetStatus]
      2005-02-03 08:48:55,246 FATAL [org.apache.axis.InternalException] Exception:
      java.lang.Exception: The OperationDesc for getStatus was not synchronized to a method of org.opcfoundation.webservices.XMLDA._1_0.Se
      rvice.
      


      Is there a solution to this, does JBoss support what I'm trying to do.

      Thanks in advance.

        • 1. Re: web service with document literal and complex types
          siano

          Hi,

          I had exactly the same problem as you and it took me quite a long time to solve this with the help of this forum.

          JBossWS does not support wrapped doc/lit messages, so you can implement only methods with one parameter.

          I did the following:

          Using Sun's JWSDP I generated the skeletons and custom types from the provided wsdl file:

           <target name="wscompile" depends="compile">
           <taskdef name="wscompile" classname="com.sun.xml.rpc.tools.ant.Wscompile" classpathref="build.classpath"/>
           <wscompile
           import="true"
           fork="true"
           define="false"
           server="false"
           keep="true"
           base="${build.classes.dir}"
           sourceBase="${build.src.dir}"
           features="wsi,donotoverride"
           mapping="${build.resources.dir}/jaxrpc.xml"
           config="${resources.dir}/wsconfig.xml">
           <classpath>
           <path refid="build.classpath"/>
           <pathelement path="${build.classes.dir}"/>
           </classpath>
           </wscompile>
           </target>
          


          Note the wsi feature, this will make wscompile generate a server skeleton, the appropriate interfaces and a jaxrpc-mapping file for a unwrapped message.

          2. move the generated foobar_Impl.java to your source tree and implement the web service method(s). (They are in the generated code, but do nothing).

          You need to write a webservice.xml and a web.xml and package all this (The generated and implemented interfaces and classes, the generated jaxrpc-mapping file, the webservice.xml, the web.xml and the provided wsdl-file) into a war file and deploy it to JBoss.

          This may or may not work (in my case it didn't).

          3. If it doesn't work, you need to provide a custom mapping for your
          complex types (included your generated parameter beans).

          This goes into a file called (that is also put into the war file)
          <deployment
           xmlns='http://xml.apache.org/axis/wsdd/'
           xmlns:java='http://xml.apache.org/axis/wsdd/providers/java'
           xmlns:soap='http://schemas.xmlsoap.org/soap/encoding/'
           xmlns:xsi='http://www.w3.org/2000/10/XMLSchema-instance'
           xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
           ...
           <typeMapping
           qname='ns1:MyMethod' xmlns:ns1='http://foobar.com/Namespace/'
           type='java:com.foobar.MyMethod'
           serializer='org.apache.axis.encoding.ser.BeanSerializerFactory'
           deserializer='org.apache.axis.encoding.ser.BeanDeserializerFactory'
           encodingStyle=''>
           </typeMapping>
           ...
          </deployment>
          


          4. Hopefully this will work. In my case it still didn't. For some reason the generated wsdd-file in $JBOSS_ROOT/server/default/data/wsdl/foobar.war contained only the return parameter as INOUT instead one IN parameter and a return value, so I also had to provide -tags in my ws4ee-deployment.xml file.

          Additionally it might help to set the loglevel in the log4j.xml config file to DEBUG for org.apache.axis, this will make the server log (among others) the transfered SOAP messages.

          Stephan

          • 2. Re: web service with document literal and complex types
            andy_wagg

            Hi Stephan,

            Thanks for that, yes it seems quite difficult to get much help with this.

            I had already found that i needed to include the wsi option with the wscompile to generate a operation with a single parameter. I haven't got as far as writing the actual implementation, my first step was just to get this to deploy and be visible from the JBoss web service view.

            My war deploys succesfully and includes the web.xml, webservices.xml and jaxrpc-mapping.xml together with all the classes.

            I'm not sure I understood step 3 about the custom mappings, is this the ws4ee-deployment.xml file?

            Unfortunately I am using a supplied wsdl file which seems to be rather complicated, but as far as I can tell I also have an operation, that takes one IN parameter and returns a parameter as per your step 4. Looking at the wsdd, this has it as an INOUT. So presumably this is why it is giving an Axis debug message in the log about not being able to convert the parameter as it's trying to convert my input parameter to my output parameter. What did you do to solve this particular problem.

            This is a fragment of my wsdl

             <s:element name="GetStatus">
             <s:complexType>
             <s:attribute name="LocaleID" type="s:string" />
             <s:attribute name="ClientRequestHandle" type="s:string" />
             </s:complexType>
             </s:element>
             <s:element name="GetStatusResponse">
             <s:complexType>
             <s:sequence>
             <s:element minOccurs="0" maxOccurs="1" name="GetStatusResult" type="s0:ReplyBase" />
             <s:element minOccurs="0" maxOccurs="1" name="Status" type="s0:ServerStatus" />
             </s:sequence>
             </s:complexType>
             </s:element>
            
             <message name="GetStatusSoapIn">
             <part name="parameters" element="s0:GetStatus" />
             </message>
             <message name="GetStatusSoapOut">
             <part name="parameters" element="s0:GetStatusResponse" />
             </message>
            
             <portType name="Service">
             <operation name="GetStatus">
             <input message="s0:GetStatusSoapIn" />
             <output message="s0:GetStatusSoapOut" />
             </operation>
            
             <binding name="Service" type="s0:Service">
             <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document" />
             <operation name="GetStatus">
             <soap:operation soapAction="http://opcfoundation.org/webservices/XMLDA/1.0/GetStatus" style="document" />
             <input>
             <soap:body use="literal" />
             </input>
             <output>
             <soap:body use="literal" />
             </output>
             </operation>
            
            


            This is a fragment of the corresponding wsdd
             <operation name='getStatus' qname='ns1:GetStatus' xmlns:ns1='http://opcfoundation.org/webservices/XMLDA/1.0/' >
             <parameter name='parameters' qname='ns1:GetStatusResponse' mode='INOUT' type='ns1:GetStatusResponse' xmlns:ns1='http://opcfounda
            tion.org/webservices/XMLDA/1.0/' />
             </operation>
            
             <typeMapping
             qname='ns1:GetStatus' xmlns:ns1='http://opcfoundation.org/webservices/XMLDA/1.0/'
             type='java:org.opcfoundation.webservices.XMLDA._1_0.GetStatus'
             serializer='org.jboss.webservice.encoding.ser.MetaDataBeanSerializerFactory'
             deserializer='org.jboss.webservice.encoding.ser.MetaDataBeanDeserializerFactory'
             encodingStyle=''>
             <typeDesc>
             <elementDesc fieldName='localeID' xmlName='LocaleID' asAttr='true'/>
             <elementDesc fieldName='clientRequestHandle' xmlName='ClientRequestHandle' asAttr='true'/>
             </typeDesc>
             </typeMapping>
            
             <typeMapping
             qname='ns1:GetStatusResponse' xmlns:ns1='http://opcfoundation.org/webservices/XMLDA/1.0/'
             type='java:org.opcfoundation.webservices.XMLDA._1_0.GetStatusResponse'
             serializer='org.jboss.webservice.encoding.ser.MetaDataBeanSerializerFactory'
             deserializer='org.jboss.webservice.encoding.ser.MetaDataBeanDeserializerFactory'
             encodingStyle=''>
             <typeDesc>
             <elementDesc fieldName='getStatusResult' xmlName='GetStatusResult'/>
             <elementDesc fieldName='status' xmlName='Status'/>
             <elementOrder> <element name='getStatusResult'/>
             <element name='status'/>
             </elementOrder> </typeDesc>
             </typeMapping>
            
            


            This is a fragment of the generated SEI
            public interface Service extends java.rmi.Remote {
             public org.opcfoundation.webservices.XMLDA._1_0.GetStatusResponse getStatus(org.opcfoundation.webservices.XMLDA._1_0.GetStatus p
            arameters) throws
             java.rmi.RemoteException;
            


            Finally, the Axis debug
            2005-02-03 12:01:53,679 DEBUG [org.apache.axis.description.ServiceDesc] Enter: syncOperationToClass org.apache.axis.description.Oper
            ationDesc
            name: getStatus
            returnQName: null
            returnType: null
            returnClass: null
            elementQName:{http://opcfoundation.org/webservices/XMLDA/1.0/}GetStatus
            soapAction: null
            style: document
            use: literal
            numInParams: 1
            method:null
             ParameterDesc[0]:
             name: {http://opcfoundation.org/webservices/XMLDA/1.0/}GetStatusResponse
             typeEntry: null
             mode: INOUT
             isReturn: false
             typeQName: {http://opcfoundation.org/webservices/XMLDA/1.0/}GetStatusResponse
             javaType: null
             inHeader: false
             outHeader: false
            
            
            2005-02-03 12:01:53,680 DEBUG [org.apache.axis.description.ServiceDesc] Sync method: public abstract org.opcfoundation.webservices.X
            MLDA._1_0.GetStatusResponse org.opcfoundation.webservices.XMLDA._1_0.Service.getStatus(org.opcfoundation.webservices.XMLDA._1_0.GetS
            tatus) throws java.rmi.RemoteException
            2005-02-03 12:01:53,680 DEBUG [org.apache.axis.description.ServiceDesc] Converting param: class org.opcfoundation.webservices.XMLDA.
            _1_0.GetStatus
            2005-02-03 12:01:53,680 DEBUG [org.apache.axis.description.ServiceDesc] Setting param class from TypeQName: class org.opcfoundation.
            webservices.XMLDA._1_0.GetStatusResponse
            2005-02-03 12:01:53,734 DEBUG [org.apache.axis.utils.JavaUtils] Not convertible: [src=class org.opcfoundation.webservices.XMLDA._1_0
            .GetStatusResponse,dest=class org.opcfoundation.webservices.XMLDA._1_0.GetStatus]
            2005-02-03 12:01:53,734 DEBUG [org.apache.axis.description.ServiceDesc] Param class is not convertible: [param=class org.opcfoundati
            on.webservices.XMLDA._1_0.GetStatusResponse,actual=class org.opcfoundation.webservices.XMLDA._1_0.GetStatus]
            2005-02-03 12:01:53,734 FATAL [org.apache.axis.InternalException] Exception:
            java.lang.Exception: The OperationDesc for getStatus was not synchronized to a method of org.opcfoundation.webservices.XMLDA._1_0.Se
            rvice.
            


            This would appear to be similair to the problem you mentioned in step 4, with the INOUT instead of an IN and a return.

            Thanks for any help you can give me,

            Andy

            • 3. Re: web service with document literal and complex types
              andy_wagg

              I figured out that all i needed was to duplicate the operations from the wsdd in the ws4ee-deployment.xml. Change them so the return type was specified and make the INOUT parameters IN with the correct types.

              Thanks for giving me some suitable pointers :)

              Andy

              • 4. Re: web service with document literal and complex types
                thomas.diesler

                This sounds like a terrible hack, lets try to get it to work in a portable way (without ws4ee-deployment.xml)

                http://jira.jboss.com/jira/browse/JBWS-116