Title: Could not convert org.apache.axis.attachments.AttachmentPart

Hello!

I have been struggeling with implementing an MMS receiver according to the MM7 specification.

3GPP's MM7 interface defines an MM7 XML schema (namespace is http://www.3gpp.org/ftp/Specs/archive/23_series/23.140/schema/REL-6-MM7-1-0) that contains the following element:

        <xsd:complexType name="contentReferenceType">
                <xsd:annotation>
                        <xsd:documentation>content element including only href</xsd:documentation>
                </xsd:annotation>
                <xsd:attribute name="href" type="xsd:anyURI" use="required"/>
                <xsd:attribute name="allowAdaptations" type="xsd:boolean" use="optional"/>
        </xsd:complexType>

This element contains a cid: URL that points to a MIME content in a SOAP with attachment message:
   <Content allowAdaptations="false" href="">


When importing this schema into a WSDL file and generating Java classes with WSDL2JAVA for the use on the server side, one gets the following Exception, when the service is called by a SOAP request containing an attachment:

[26.07.06 10:03:31:163 CEST]  3410b26 BeanPropertyT E org.apache.axis.encoding.ser.BeanPropertyTarget  Could not convert org.apache.axis.attachments.AttachmentPart to bean field 'content', type at.mobilkom.asmp.mm7.wsdl.ContentReferenceType

[26.07.06 10:03:31:173 CEST]  3410b26 EXCEPTIONS    I org.apache.axis.EXCEPTIONS  AxisFault:
[26.07.06 10:03:31:273 CEST]  3410b26 EXCEPTIONS    I org.apache.axis.EXCEPTIONS  TRAS0014I: Die folgende Ausnahmebedingung wurde protokolliert: AxisFault

 faultCode: {http://schemas.xmlsoap.org/soap/envelope/}Server.userException
 faultSubcode:
 faultString: java.lang.IllegalArgumentException: argument type mismatch
 faultActor:
 faultNode:
 faultDetail:
        {http://xml.apache.org/axis/}stackTrace:java.lang.IllegalArgumentException: argument type mismatch
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:85)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:58)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:60)
        at java.lang.reflect.Method.invoke(Method.java:391)
        at org.apache.axis.utils.BeanPropertyDescriptor.set(BeanPropertyDescriptor.java:142)
        at org.apache.axis.encoding.ser.BeanPropertyTarget.set(BeanPropertyTarget.java:75)
        at org.apache.axis.encoding.DeserializerImpl.valueComplete(DeserializerImpl.java:249)
        at org.apache.axis.encoding.DeserializerImpl.startElement(DeserializerImpl.java:388)
        at org.apache.axis.encoding.DeserializationContext.startElement(DeserializationContext.java:1048)
        at org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:165)
        at org.apache.axis.message.MessageElement.publishToHandler(MessageElement.java:1141)
        at org.apache.axis.message.RPCElement.deserialize(RPCElement.java:236)
        at org.apache.axis.message.RPCElement.getParams(RPCElement.java:384)
        at org.apache.axis.providers.java.RPCProvider.processMessage(RPCProvider.java:81)
        at org.apache.axis.providers.java.JavaProvider.invoke(JavaProvider.java:323)
        at org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java:32)
        at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
        at org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
        at org.apache.axis.handlers.soap.SOAPService.invoke(SOAPService.java:453)
        at org.apache.axis.server.AxisServer.invoke(AxisServer.java:281)
        at org.apache.axis.transport.http.AxisServlet.doPost(AxisServlet.java:699)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
        at org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
        at com.ibm.ws.webcontainer.servlet.StrictServletInstance.doService(StrictServletInstance.java:110)
        at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet._service(StrictLifecycleServlet.java:174)
        at com.ibm.ws.webcontainer.servlet.IdleServletState.service(StrictLifecycleServlet.java:313)
        at com.ibm.ws.webcontainer.servlet.StrictLifecycleServlet.service(StrictLifecycleServlet.java:116)
        at com.ibm.ws.webcontainer.servlet.ServletInstance.service(ServletInstance.java:283)
        at com.ibm.ws.webcontainer.servlet.ValidServletReferenceState.dispatch(ValidServletReferenceState.java:42)
        at com.ibm.ws.webcontainer.servlet.ServletInstanceReference.dispatch(ServletInstanceReference.java:40)
        at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.handleWebAppDispatch(WebAppRequestDispatcher.java:1019)

        at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:592)
        at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:204)
        at com.ibm.ws.webcontainer.srt.WebAppInvoker.doForward(WebAppInvoker.java:125)
        at com.ibm.ws.webcontainer.srt.WebAppInvoker.handleInvocationHook(WebAppInvoker.java:286)
        at com.ibm.ws.webcontainer.cache.invocation.CachedInvocation.handleInvocation(CachedInvocation.java:71)
        at com.ibm.ws.webcontainer.srp.ServletRequestProcessor.dispatchByURI(ServletRequestProcessor.java:182)
        at com.ibm.ws.webcontainer.oselistener.OSEListenerDispatcher.service(OSEListener.java:334)
        at com.ibm.ws.webcontainer.http.HttpConnection.handleRequest(HttpConnection.java:56)
        at com.ibm.ws.http.HttpConnection.readAndHandleRequest(HttpConnection.java:615)
        at com.ibm.ws.http.HttpConnection.run(HttpConnection.java:439)
        at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:912)


The reason for this is rooted in the org.apache.axis.encoding.DeserializerImpl class in method startElement():

Here it is detected that the element references an AttachmentPart and the following code gets executed:

                if( !href.startsWith("#") && defaultType != null && ref instanceof Part ){
                    //For attachments this is the end of the road-- invoke deserializer
                    Deserializer dser = context.getDeserializerForType(defaultType );
                    if(null != dser){         
                      dser.startElement(namespace, localName,
                             prefix, attributes,
                             context);
                      ref = dser.getValue();      
                    }
               }

The default type is imlpemented by a BeanDeserialize, that gets called with startElement(). BeanDeserialzer extends DeserializerImpl and BeanDeserialzer.startElement() calls super.startElement(). Thus DeserializerImpl.startElement() gets called a second time and returns again an AttachmentPart as object reference (as there is sill the href attribute). The BeanPropertyTarget.set() method later on tries to set the Java Bean with an AttachmentPart and fails with above exception.

I have quickly solved this bug by adding to the classes Deserializer, DeserializerImpl and BeanDeserialzer the method

    public void startElement(String namespace, String localName,
            String qName, Attributes attributes,
            DeserializationContext context, boolean ignoreHref)
    throws SAXException;
   
where the existing code calls now

    public void startElement(String namespace, String localName,
            String prefix, Attributes attributes,
            DeserializationContext context)
    throws SAXException
    {
       startElement(namespace, localName, prefix, attributes, context, false);
    }


In DeserializerImpl.startElement() I have extended the href check by:

        String href = "">
        if (href != null && !ignoreHref) {
       
This may not be the most elegant solution, but it works.

It would be very nice, if one of the Axis gurus could confirm, that this is indeed a bug and perhaps propose some good solution.

regards
Rudolf

Reply via email to