8 Replies Latest reply on Mar 30, 2007 10:13 AM by czhao07

    How to register SerializerFactory and DeSerializerFactory fo

    czhao07

      I am implementing a WS client with JBossWS to access a third-party web service, one of the service operations takes a xsd:anyType type as the parameter, and it gets mapped to SOAPElement in the wstools generated code. When I invoke the service, I got this exception:

      javax.xml.rpc.JAXRPCException: Cannot obtain serializer factory for: [xmlType={http://www.w3.org/2001/XMLSchema}anyType,javaType=interface javax.xml.soap.SOAPElement]

      This article (http://wiki.jboss.org/wiki/Wiki.jsp?page=WS4EETypeMapping) talks about how to add type mappings for service endpoint, not the WS client. But anyway, I tried to add file ws4ee-deployment.xml to my client's META-INF folder with following mapping:

      <typeMapping qname="xsd:anyType"
      xmlns:xsd="http://www.w3.org/2001/XMLSchema"
      serializer="org.jboss.ws.jaxrpc.encoding.ElementSerializerFactory" deserializer="org.jboss.ws.jaxrpc.encoding.ElementDeserializerFactory"
      type="java:javax.xml.soap.SOAPElement"
      encodingStyle="" />

      and it didn't work.

      Does anyone know a solution to this issue?

      Much thanks!

        • 1. Re: How to register SerializerFactory and DeSerializerFactor
          jason.greene

          What version of JBossWS are you using? ws4ee-deployment.xml was only valid on jboss-ws4ee which was the older axis based stack.

          • 2. Re: How to register SerializerFactory and DeSerializerFactor
            czhao07

            I am using JBossWS 1.0.3.GA.

            • 3. Re: How to register SerializerFactory and DeSerializerFactor
              jason.greene

              I believe this was fixed in 1.0.4. Although you can work around the issue by changing your mapping file and code to use a org.w3c.dom.Element instead.

              • 4. Re: How to register SerializerFactory and DeSerializerFactor
                czhao07

                I just upgrade JBossWS to 1.0.4, but still have the same problem:

                javax.xml.rpc.JAXRPCException: Cannot obtain serializer factory for: [xmlType={http://www.w3.org/2001/XMLSchema}anyType,javaType=interface javax.xml.soap.SOAPElement]
                at org.jboss.ws.soap.SOAPContentElement.getSerializerFactory(SOAPContentElement.java:377)
                at org.jboss.ws.soap.SOAPContentElement.getXMLFragment(SOAPContentElement.java:143)
                at org.jboss.ws.soap.SOAPContentElement.expandToDOM(SOAPContentElement.java:802)

                • 5. Re: How to register SerializerFactory and DeSerializerFactor
                  czhao07

                  I think I found the problem. The web service I need to call uses soap encoding style (http://schemas.xmlsoap.org/soap/encoding/), hence EncodedTypeMapping is used which registers type mapping for xsd:anyType as this:

                  // register mapping for xsd:anyType
                  registerInternal(SOAPElement.class, Constants.TYPE_SOAP11_ANYTYPE, new SOAPElementSerializerFactory(), new SOAPElementDeserializerFactory());
                  registerInternal(Element.class, Constants.TYPE_SOAP11_ANYTYPE, new ElementSerializerFactory(), new ElementDeserializerFactory());

                  In above code, it registers (De)SerializerFactory for a wrong QName. While the fix in LiteralTypeMapping is correct:

                  // register mapping for xsd:anyType
                  registerInternal(SOAPElement.class, Constants.TYPE_LITERAL_ANYTYPE, new SOAPElementSerializerFactory(), new SOAPElementDeserializerFactory());
                  registerInternal(Element.class, Constants.TYPE_LITERAL_ANYTYPE, new ElementSerializerFactory(), new ElementDeserializerFactory());

                  So I think the above lines of code should be moved to TypeMappingImpl.registerStandardLiteralTypes() in order to fix the problem with both literal and soap encoding styles.

                  • 6. Re: How to register SerializerFactory and DeSerializerFactor
                    thomas.diesler

                    The LiteralTypeMapping is constructed like this

                     public LiteralTypeMapping()
                     {
                     ...
                    
                     registerStandardLiteralTypes();
                    
                     ...
                    
                     // register mapping for xsd:anyType
                     register(SOAPElement.class, Constants.TYPE_LITERAL_ANYTYPE, new SOAPElementSerializerFactory(), new SOAPElementDeserializerFactory());
                     register(Element.class, Constants.TYPE_LITERAL_ANYTYPE, new ElementSerializerFactory(), new ElementDeserializerFactory());
                     }
                    


                    Unfortunatly, it is not commented why xsd:antType is not considered as a standard literal type. Maybe only because it is not by the spec.

                    I hesitate to have this changed since in favour of rpc/encoded because it might break anyType handling for literal users.

                    However, lets have a jira for it

                    http://jira.jboss.org/jira/browse/JBWS-1595




                    • 7. Re: How to register SerializerFactory and DeSerializerFactor
                      thomas.diesler

                      This change might work for you

                      
                       public EncodedTypeMapping()
                       {
                       registerStandardLiteralTypes();
                       registerStandardSOAP11EncodedTypes();
                      
                       // register mapping for xsd:anyType
                       register(SOAPElement.class, Constants.TYPE_LITERAL_ANYTYPE, new SOAPElementSerializerFactory(), new SOAPElementDeserializerFactory());
                       register(Element.class, Constants.TYPE_LITERAL_ANYTYPE, new ElementSerializerFactory(), new ElementDeserializerFactory());
                      
                       // register mapping for soap11-enc:anyType
                       register(SOAPElement.class, Constants.TYPE_SOAP11_ANYTYPE, new SOAPElementSerializerFactory(), new SOAPElementDeserializerFactory());
                       register(Element.class, Constants.TYPE_SOAP11_ANYTYPE, new ElementSerializerFactory(), new ElementDeserializerFactory());
                       }
                      


                      • 8. Re: How to register SerializerFactory and DeSerializerFactor
                        czhao07

                        Yep, this should work. My workaround is to change the WSDL to not use soap encoding style, now it works just fine.

                        -Chunyun Zhao