5 Replies Latest reply on Jun 10, 2004 8:40 AM by bensorek

    Cannot deserialise JavaBeans

    cdog

      Hi,
      I've been deploying web services in JBoss 3.2.3 using the method given in the JBoss.NET article at http://www.nsdev.org/jboss/stories/jboss-net.html. Everything works fine when using primative types and Strings for the web service parameter types. However, I can not get the service to work when I use a JavaBean as the parameter type. The exception is as follows:

      org.xml.sax.SAXException: Deserializing parameter 'in0': could not find deserializer for type {http://datatranferobjects.example.cdog.com}SimpleDto


      In this post I have included
      The source for JavaBean being passed as a parameter
      The source for the EJB which is exposing the service
      The jbossnet element from my build.xml
      The web-service.xml file generated
      The wsdl for the service
      The soap request and reponse message


      The JavaBean passed as a parameter to the web service is SimpleDto This code and xdoc tags for this are as follows:
      package com.cdog.example.datatranferobjects;
      
      import java.io.Serializable;
      
      /**
       * @jboss-net.xml-schema urn="SimpleService:SimpleDto"
       */
      public class SimpleDto implements Serializable {
       private String message;
      
       public SimpleDto(){
       }
       public String getMessage() {
       return message;
       }
       public void setMessage(String message) {
       this.message = message;
       }
      }


      The bean providing the service is the SimpleBean. This is as follows:

      package com.cdog.example.service.implementation;
      
      import java.rmi.RemoteException;
      
      import javax.ejb.CreateException;
      import javax.ejb.EJBException;
      import javax.ejb.SessionBean;
      import javax.ejb.SessionContext;
      
      import com.cdog.example.datatranferobjects.SimpleDto;
      
      /**
       * @ejb:bean
       * name = "SimpleBean"
       * type="Stateless"
       * view-type = "both"
       * jndi-name = "SimpleBean"
       *
       * @jboss-net.web-service urn="Simple"
       * @ejb:transaction
       * type="Required"
       *
       */
      public class SimpleBean implements SessionBean {
      
       /**
       *
       * @ejb.interface-method view-type="both"
       *
       * @jboss-net.web-method
       *
       */
       public void simpleParam(SimpleDto dto){
       System.out.println(dto.getMessage());
       }
      
      
       /**
       * @ejb.interface-method view-type="both"
       *
       * @jboss-net.web-method
       *
       */
       public void evenSimpler(final String s){
       System.out.println(s);
       } ...
      
      }



      The jbossnet element and its properties are as follows:

      <property name = "namespace" value = "http://com/cdog/service/SimpleService"/>
      <property name = "webservice.name" value = "SimpleService"/>
      
      <jbossnet webDeploymentName = "${webservice.name}"
       prefix = "SimpleService"
       destdir = "${build.dir}/webservice/META-INF"
       targetNameSpace = "${namespace}"/>


      The web-service.xml generated from the above is as follows:
      <?xml version="1.0" encoding="UTF-8"?>
      
      <!-- -->
      <!-- This JBoss.Net Web Service Descriptor has been generated by XDoclet -->
      <!-- and is brought to you by F. M. Brier, C. G. Jung and J. Essington -->
      <!-- -->
      
      <deployment
       name="SimpleService"
       xmlns="http://xml.apache.org/axis/wsdd/"
       targetNamespace="http://com/cdog/service/SimpleService"
       xmlns:SimpleService="http://com/cdog/service/SimpleService"
       xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
      
      <!-- The following are declarations of service endpoints targetted to
       session beans -->
      
       <service name="Simple" provider="Handler">
       <parameter name="handlerClass" value="org.jboss.net.axis.server.EJBProvider"/>
       <parameter name="beanJndiName" value="SimpleBeanLocal"/>
       <parameter name="allowedMethods" value="evenSimpler simpleParam "/>
       <requestFlow name="SimpleRequest">
       </requestFlow>
       <responseFlow name="SimpleResponse">
       </responseFlow>
       </service>
      
      <!-- The following are typemappings for entity beans for implementing
       the implicit web-service value-object pattern -->
      
      <!-- The following are typemappings for bean-type value-objects -->
      
       <typeMapping
       qname="SimpleService:SimpleDto"
       type="java:com.cdog.example.datatranferobjects.SimpleDto"
       serializer="org.apache.axis.encoding.ser.BeanSerializerFactory"
       deserializer="org.apache.axis.encoding.ser.BeanDeserializerFactory"
       encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
      
      <!-- There follow merged custom web service descriptions -->
      
      </deployment>


      When built the service deploys fine and the following wsdl is produced.

      <?xml version="1.0" encoding="UTF-8" ?>
      - <wsdl:definitions targetNamespace="http://localhost:8080/jboss-net/services/Simple" xmlns="http://schemas.xmlsoap.org/wsdl/" xmlns:apachesoap="http://xml.apache.org/xml-soap" xmlns:impl="http://localhost:8080/jboss-net/services/Simple" xmlns:intf="http://localhost:8080/jboss-net/services/Simple" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:tns1="http://com/cdog/service/SimpleService" xmlns:tns2="http://net.jboss.org/jmx" xmlns:tns3="http://datatranferobjects.example.cdog.com" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      - <wsdl:types>
      - <schema targetNamespace="http://com/cdog/service/SimpleService" xmlns="http://www.w3.org/2001/XMLSchema">
       <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
      - <complexType name="SimpleDto">
      - <sequence>
       <element name="message" nillable="true" type="xsd:string" />
       </sequence>
       </complexType>
       </schema>
      - <schema targetNamespace="http://net.jboss.org/jmx" xmlns="http://www.w3.org/2001/XMLSchema">
       <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
      - <simpleType name="ObjectNameType">
      - <simpleContent>
       <extension base="xsd:string" />
       </simpleContent>
       </simpleType>
       </schema>
      - <schema targetNamespace="http://datatranferobjects.example.cdog.com" xmlns="http://www.w3.org/2001/XMLSchema">
       <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
      - <complexType name="SimpleDto">
      - <sequence>
       <element name="message" nillable="true" type="xsd:string" />
       </sequence>
       </complexType>
       </schema>
       </wsdl:types>
      - <wsdl:message name="evenSimplerRequest">
       <wsdl:part name="in0" type="xsd:string" />
       </wsdl:message>
       <wsdl:message name="evenSimplerResponse" />
       <wsdl:message name="simpleParamResponse" />
      - <wsdl:message name="simpleParamRequest">
       <wsdl:part name="in0" type="tns3:SimpleDto" />
       </wsdl:message>
      - <wsdl:portType name="SimpleBeanLocal">
      - <wsdl:operation name="simpleParam" parameterOrder="in0">
       <wsdl:input message="impl:simpleParamRequest" name="simpleParamRequest" />
       <wsdl:output message="impl:simpleParamResponse" name="simpleParamResponse" />
       </wsdl:operation>
      - <wsdl:operation name="evenSimpler" parameterOrder="in0">
       <wsdl:input message="impl:evenSimplerRequest" name="evenSimplerRequest" />
       <wsdl:output message="impl:evenSimplerResponse" name="evenSimplerResponse" />
       </wsdl:operation>
       </wsdl:portType>
      - <wsdl:binding name="SimpleSoapBinding" type="impl:SimpleBeanLocal">
       <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
      - <wsdl:operation name="simpleParam">
       <wsdlsoap:operation soapAction="Simple" />
      - <wsdl:input name="simpleParamRequest">
       <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://interfaces.service.example.cdog.com" use="encoded" />
       </wsdl:input>
      - <wsdl:output name="simpleParamResponse">
       <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/jboss-net/services/Simple" use="encoded" />
       </wsdl:output>
       </wsdl:operation>
      - <wsdl:operation name="evenSimpler">
       <wsdlsoap:operation soapAction="Simple" />
      - <wsdl:input name="evenSimplerRequest">
       <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://interfaces.service.example.cdog.com" use="encoded" />
       </wsdl:input>
      - <wsdl:output name="evenSimplerResponse">
       <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/jboss-net/services/Simple" use="encoded" />
       </wsdl:output>
       </wsdl:operation>
       </wsdl:binding>
      - <wsdl:service name="SimpleBeanLocalService">
      - <wsdl:port binding="impl:SimpleSoapBinding" name="Simple">
       <wsdlsoap:address location="http://localhost:8080/jboss-net/services/Simple" />
       </wsdl:port>
       </wsdl:service>
       </wsdl:definitions>


      A java client is build from this wsdl using Axis wsdl2java. The following two message are the request and response message as view with tcpmonitor

      Request:

      POST /jboss-net/services/Simple HTTP/1.0
      
      Content-Type: text/xml; charset=utf-8
      
      Accept: application/soap+xml, application/dime, multipart/related, text/*
      
      User-Agent: Axis/1.1
      
      Host: 127.0.0.1
      
      Cache-Control: no-cache
      
      Pragma: no-cache
      
      SOAPAction: "Simple"
      
      Content-Length: 770
      
      
      
      <?xml version="1.0" encoding="UTF-8"?>
      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <soapenv:Body>
       <ns1:simpleParam soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://interfaces.service.example.cdog.com">
       <in0 href="#id0"/>
       </ns1:simpleParam>
       <multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:SimpleDto" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="http://datatranferobjects.example.cdog.com">
       <message xsi:type="xsd:string">SimpleDto message</message>
       </multiRef>
       </soapenv:Body>
      </soapenv:Envelope>


      Response: (you can probably guess what this looks like buy now)

      HTTP/1.1 500 Internal Server Error
      
      Content-Type: text/xml;charset=utf-8
      
      Date: Fri, 14 May 2004 15:37:42 GMT
      
      Server: Apache-Coyote/1.1
      
      Connection: close
      
      
      
      <?xml version="1.0" encoding="UTF-8"?>
      <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
       <soapenv:Body>
       <soapenv:Fault>
       <faultcode>soapenv:Server.userException</faultcode>
       <faultstring>org.xml.sax.SAXException: Deserializing parameter &apos;in0&apos;: could not find deserializer for type {http://datatranferobjects.example.cdog.com}SimpleDto</faultstring>
       <detail/>
       </soapenv:Fault>
       </soapenv:Body>
      </soapenv:Envelope>


        • 1. Re: Cannot deserialise JavaBeans
          takenori

          Hi,

          Do you include your SimpleDto
          in ejbDoclet task?

          This is one of the most common error.

          Takenori,

          • 2. Re: Cannot deserialise JavaBeans
            cdog

            Hi,

            I'm pretty sure it is included OK. The typeMapping element for the SimpleDto in the web-service.xml is generated by Xdoclet.
            I checked by removing the fileset that referenced to the SimpleDto this resulted in the typeMapping element is not being included in the web-service.xml.

            • 3. Re: Cannot deserialise JavaBeans
              starksm64

              The wsdl file generated by the axis servlet incorrectly includes types from all deployments. You can see that the SimpleDto exists under two different namespaces, and the client generation happened to choose the wrong one. Cleanup the wsdl by hand and re-run the code generation.

              • 4. Re: Cannot deserialise JavaBeans
                cdog

                Hi,
                Thanks for that Scott. I seem to have got a bit further. I've hacked the
                wsdl as suggested and this has got rid of the previous error, but now
                I'm getting a bad type error. I've included the hacked wsdl and the
                error at the end of this post. You can see from the error that the
                deserialiser is now being found, but I still can't successfully deserialise the bean. Any ideas?

                cdog

                AxisFault
                 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
                 faultSubcode:
                 faultString: org.xml.sax.SAXException: Bad types (class com.cdog.example.datatranferobjects.SimpleDto -&gt; class com.cdog.example.datatranferobjects.SimpleDto)
                 faultActor:
                 faultNode:
                 faultDetail:
                 {http://xml.apache.org/axis/}stackTrace: AxisFault
                 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
                 faultSubcode:
                 faultString: org.xml.sax.SAXException: Bad types (class com.cdog.example.datatranferobjects.SimpleDto -&amp;gt; class com.cdog.example.datatranferobjects.SimpleDto)
                 faultActor:
                 faultNode:
                 faultDetail:
                
                org.xml.sax.SAXException: Bad types (class com.cdog.example.datatranferobjects.SimpleDto -&gt; class com.cdog.example.datatranferobjects.SimpleDto)
                 at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:260)
                 at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:169)
                 at org.apache.axis.encoding.DeserializationContextImpl.endElement(DeserializationContextImpl.java:1015)
                 at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
                 at org.apache.crimson.parser.Parser2.content(Unknown Source)
                 at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
                 at org.apache.crimson.parser.Parser2.content(Unknown Source)
                 at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
                 at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
                 at org.apache.crimson.parser.Parser2.parse(Unknown Source)
                 at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
                 at javax.xml.parsers.SAXParser.parse(Unknown Source)
                 at org.apache.axis.encoding.DeserializationContextImpl.parse(DeserializationContextImpl.java:242)
                 at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:538)
                 at org.apache.axis.Message.getSOAPEnvelope(Message.java:376)
                 at org.apache.axis.client.Call.invokeEngine(Call.java:2583)
                 at org.apache.axis.client.Call.invoke(Call.java:2553)
                 at org.apache.axis.client.Call.invoke(Call.java:2248)
                 at org.apache.axis.client.Call.invoke(Call.java:2171)
                 at org.apache.axis.client.Call.invoke(Call.java:1691)
                 at localhost.jboss_net.services.Simple.SimpleSoapBindingStub.simpleParam(SimpleSoapBindingStub.java:142)
                 at com.retail_logic.clienttest.AuithClient.main(AuithClient.java:60)
                
                
                org.xml.sax.SAXException: Bad types (class com.cdog.example.datatranferobjects.SimpleDto -> class com.cdog.example.datatranferobjects.SimpleDto)
                 at org.apache.axis.message.SOAPFaultBuilder.createFault(SOAPFaultBuilder.java:260)
                 at org.apache.axis.message.SOAPFaultBuilder.endElement(SOAPFaultBuilder.java:169)
                 at org.apache.axis.encoding.DeserializationContextImpl.endElement(DeserializationContextImpl.java:1015)
                 at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
                 at org.apache.crimson.parser.Parser2.content(Unknown Source)
                 at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
                 at org.apache.crimson.parser.Parser2.content(Unknown Source)
                 at org.apache.crimson.parser.Parser2.maybeElement(Unknown Source)
                 at org.apache.crimson.parser.Parser2.parseInternal(Unknown Source)
                 at org.apache.crimson.parser.Parser2.parse(Unknown Source)
                 at org.apache.crimson.parser.XMLReaderImpl.parse(Unknown Source)
                 at javax.xml.parsers.SAXParser.parse(Unknown Source)
                 at org.apache.axis.encoding.DeserializationContextImpl.parse(DeserializationContextImpl.java:242)
                 at org.apache.axis.SOAPPart.getAsSOAPEnvelope(SOAPPart.java:538)
                 at org.apache.axis.Message.getSOAPEnvelope(Message.java:376)
                 at org.apache.axis.client.Call.invokeEngine(Call.java:2583)
                 at org.apache.axis.client.Call.invoke(Call.java:2553)
                 at org.apache.axis.client.Call.invoke(Call.java:2248)
                 at org.apache.axis.client.Call.invoke(Call.java:2171)
                 at org.apache.axis.client.Call.invoke(Call.java:1691)
                 at localhost.jboss_net.services.Simple.SimpleSoapBindingStub.simpleParam(SimpleSoapBindingStub.java:142)
                 at com.retail_logic.clienttest.AuithClient.main(AuithClient.java:60)


                Here's the hacked wsdl
                <!--?xml version="1.0" encoding="UTF8" ?-->
                <!-- -->
                 <wsdl:definitions targetNamespace="http://localhost:8080/jboss-net/services/Simple"
                 xmlns="http://schemas.xmlsoap.org/wsdl/"
                 xmlns:apachesoap="http://xml.apache.org/xml-soap"
                 xmlns:impl="http://localhost:8080/jboss-net/services/Simple"
                 xmlns:intf="http://localhost:8080/jboss-net/services/Simple"
                 xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
                 xmlns:tns1="http://com/cdog/service/SimpleService"
                 xmlns:tns2="http://net.jboss.org/jmx"
                
                 xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
                 xmlns:wsdlsoap="http://schemas.xmlsoap.org/wsdl/soap/"
                 xmlns:xsd="http://www.w3.org/2001/XMLSchema">
                 <wsdl:types>
                
                 <schema targetNamespace="http://com/cdog/service/SimpleService" xmlns="http://www.w3.org/2001/XMLSchema">
                <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
                 <complexType name="SimpleDto">
                 <sequence>
                <element name="message" nillable="true" type="xsd:string" />
                 </sequence>
                 </complexType>
                 </schema>
                 <schema targetNamespace="http://net.jboss.org/jmx" xmlns="http://www.w3.org/2001/XMLSchema">
                 <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
                 <simpleType name="ObjectNameType">
                 <simpleContent>
                 <extension base="xsd:string" />
                 </simpleContent>
                 </simpleType>
                 </schema>
                 <!--schema targetNamespace="http://datatranferobjects.example.cdog.com" xmlns="http://www.w3.org/2001/XMLSchema">
                 <import namespace="http://schemas.xmlsoap.org/soap/encoding/" />
                 <complexType name="SimpleDto">
                 <sequence>
                 <element name="message" nillable="true" type="xsd:string" />
                 </sequence>
                 </complexType>
                 </schema-->
                 </wsdl:types>
                 <wsdl:message name="evenSimplerRequest">
                 <wsdl:part name="in0" type="xsd:string" />
                 </wsdl:message>
                 <wsdl:message name="evenSimplerResponse" />
                 <wsdl:message name="simpleParamResponse" />
                 <wsdl:message name="simpleParamRequest">
                 <wsdl:part name="in0" type="tns1:SimpleDto" />
                 </wsdl:message>
                 <wsdl:portType name="SimpleBeanLocal">
                 <wsdl:operation name="simpleParam" parameterOrder="in0">
                 <wsdl:input message="impl:simpleParamRequest" name="simpleParamRequest" />
                 <wsdl:output message="impl:simpleParamResponse" name="simpleParamResponse" />
                 </wsdl:operation>
                 <wsdl:operation name="evenSimpler" parameterOrder="in0">
                 <wsdl:input message="impl:evenSimplerRequest" name="evenSimplerRequest" />
                 <wsdl:output message="impl:evenSimplerResponse" name="evenSimplerResponse" />
                 </wsdl:operation>
                 </wsdl:portType>
                 <wsdl:binding name="SimpleSoapBinding" type="impl:SimpleBeanLocal">
                 <wsdlsoap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
                 <wsdl:operation name="simpleParam">
                 <wsdlsoap:operation soapAction="Simple" />
                 <wsdl:input name="simpleParamRequest">
                 <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://interfaces.service.example.cdog.com" use="encoded" />
                 </wsdl:input>
                 <wsdl:output name="simpleParamResponse">
                 <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/jboss-net/services/Simple" use="encoded" />
                 </wsdl:output>
                 </wsdl:operation>
                 <wsdl:operation name="evenSimpler">
                 <wsdlsoap:operation soapAction="Simple" />
                 <wsdl:input name="evenSimplerRequest">
                 <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://interfaces.service.example.cdog.com" use="encoded" />
                 </wsdl:input>
                 <wsdl:output name="evenSimplerResponse">
                 <wsdlsoap:body encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" namespace="http://localhost:8080/jboss-net/services/Simple" use="encoded" />
                 </wsdl:output>
                 </wsdl:operation>
                 </wsdl:binding>
                 <wsdl:service name="SimpleBeanLocalService">
                 <wsdl:port binding="impl:SimpleSoapBinding" name="Simple">
                 <wsdlsoap:address location="http://localhost:8080/jboss-net/services/Simple" />
                 </wsdl:port>
                 </wsdl:service>
                 </wsdl:definitions>


                • 5. Re: Cannot deserialise JavaBeans

                  I had the same problem, but i didn't hack the wsdl.
                  However in the client code the qname i would use for the SimpleDto is: http://com/cdog/service/SimpleService:SimpleDto
                  and not
                  SimpleService:SimpleDto.
                  For some reason that worked!