Title: Problem with custom serializer

Hi all

Hope no-one minds me sending all this information, but I've been stuck on this for a couple of days now and really need some help, so I've included all the information I could think would be useful in figuring this one out...

I'm trying to develop a custom (de)serializer for java objects that I need to pass as a parameter to a method on my SOAP service. When I run my client, the serializer works fine and posts the XML to the server. However before the deserializer on the server even gets to see the XML I get this horrible little NPE:

java.lang.NullPointerException 
at org.apache.soap.util.StringUtils.getClassName(StringUtils.java:90)  
at org.apache.soap.util.MethodUtils.callToString(MethodUtils.java:237) 
at org.apache.soap.util.MethodUtils.access$1(MethodUtils.java:72)      
at org.apache.soap.util.MethodUtils$MoreSpecific.getMostSpecific(MethodUtils.java:448) 
at org.apache.soap.util.MethodUtils.getEntryPoint(MethodUtils.java:183)        
at org.apache.soap.util.MethodUtils.getMethod(MethodUtils.java:548)    
at org.apache.soap.util.MethodUtils.getMethod(MethodUtils.java:528)    
at org.apache.soap.server.RPCRouter.invoke(RPCRouter.java:114) 
at org.apache.soap.providers.RPCJavaProvider.invoke(RPCJavaProvider.java:129)  
at org.apache.soap.server.http.RPCRouterServlet.doPost(RPCRouterServlet.java:287)

grrrrrrr!

I stepped through the SOAP code and discovered that is caused by an empty array of Class[] argTypes in the MethodUtils class. Now I am assuming that means I have constructed my XML message badly, but at that point I run out of ideas. Although I do suspect that it could have something to do with the namespaces... <clutches_straws/> 

This is the XML that is generated by my serializer:

<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/1999/XMLSchema-instance" xmlns:xsd="http://www.w3.org/1999/XMLSchema">

 <SOAP-ENV:Body>
  <ns1:send xmlns:ns1="urn:xml-soap-commsgw" SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
   <message xmlns:ns2="urn:commsgw" xsi:type="ns2:WapPush" />
  </ns1:send>
 </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Note that:
- "urn:xml-soap-commsgw" is the ID of my SOAP service
- "send" is the name of the method on my SOAP service that I am invoking
- "send" takes a parameter of type "WapPush"

My serializer doesn't yet populate all the data from my WapPush object yet, which is why you can see it is an empty XML node.

Here's the type mapping descriptor:

<isd:service xmlns:isd="http://xml.apache.org/xml-soap/deployment" id="urn:xml-soap-commsgw">
        <isd:provider type="java" scope="Application" methods="send">
                <isd:java class="com.mycompany.mysoapservice"/>
        </isd:provider>
        <isd:faultListener>org.apache.soap.server.DOMFaultListener</isd:faultListener>
        <isd:mappings>
                <isd:map encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
                         xmlns:x="urn:commsgw"  
                         qname="x:WapPush"
                 javaType="com.mycompany.WapPushMessage"
                         java2XMLClassName="com.mycompany.DeliverableSerializer"
                         xml2JavaClassName="com.mycompany.DeliverableSerializer"/>
        </isd:mappings>
</isd:service>


Here's a snippet of the relevant client code:

// heres my custom object that I'm trying to pass over
WapPushMessage msg = new WAPPushMessage();
// heres my custom (de)serializer instance
DeliverableSerializer delSer = new DeliverableSerializer();
// the rest is all the standard stuff
SOAPMappingRegistry smr = new SOAPMappingRegistry();
smr.mapTypes(Constants.NS_URI_SOAP_ENC,new QName("urn:commsgw", "WapPush"),WapPushMessage.class, delSer, delSer);
Response r=null;
Call c=new Call();
Vector parameters = new Vector();
c.setSOAPMappingRegistry(smr);
c.setTargetObjectURI ("urn:xml-soap-commsgw");
c.setMethodName ("send");
c.setEncodingStyleURI(Constants.NS_URI_SOAP_ENC);
parameters.addElement (new Parameter("message", WapPushMessage.class, msg, null));
c.setParams (parameters);
r = c.invoke ( new URL("http://"+host+":"+port+"/soap/servlet/rpcrouter"), "" );


And here is the marshall method from my serializer. Note that it doesn't currently do much:

  public void marshall(String inScopeEncStyle, Class javaType, Object src,
                       Object context, Writer sink, NSStack nsStack,
                       XMLJavaMappingRegistry xjmr, SOAPContext ctx)
    throws IllegalArgumentException, IOException
  {
    nsStack.pushScope();
    if(!(src instanceof Deliverable)){
      throw new IllegalArgumentException("Tried to pass a '" + src.getClass().toString() +
                                                  "' to DeliverableSerializer");
    }
    Deliverable message = (Deliverable) src;
    if (message == null)
    {
      SoapEncUtils.generateNullStructure(inScopeEncStyle,
                                     javaType,
                                     context,
                                     sink,
                                     nsStack,
                                     xjmr);
    }
    else
    {
      SoapEncUtils.generateStructureHeader(inScopeEncStyle,
                                         javaType,
                                         context,
                                         sink,
                                         nsStack,
                                         xjmr);
      sink.write("</" + context + '>');
    }
    nsStack.popScope();
  }


Whew! That was a mouthful. If anyone is still reading this and has any inkling of an idea as to what the problem could be, I'll be immensely grateful. Knowing me its probably an ommitted speech mark or bracket sonewhere...

Regards
Nick

Reply via email to