I'm getting a class cast exception on the return value of my service call (both server & client generated using wsdl2java)
 
        public java.lang.String _import(com.fcg.dmsl.fdk.services.common.WebServiceValueObject properties, javax.activation.DataHandler theDocument) throws java.rmi.RemoteException {
        ...
        setRequestHeaders(_call);
        setAttachments(_call);
        // *** This should be a java.lang.String.  Instead, its an instance of the same typed as the 1st argument (properties)
        java.lang.Object _resp = _call.invoke(new java.lang.Object[] {properties, theDocument});
 
        if (_resp instanceof java.rmi.RemoteException) {
            throw (java.rmi.RemoteException)_resp;
        }
        else {
            extractAttachments(_call);
            try {
                return (java.lang.String) _resp;
            } catch (java.lang.Exception _exception) {
                // *** Which eventually causes the ClassCastException here
                return (java.lang.String) org.apache.axis.utils.JavaUtils.convert(_resp, java.lang.String.class);
            }
        }
I think I traced this down to the following code in
 
package org.apache.axis.message;
...
public class BodyBuilder extends SOAPHandler
...
    public SOAPHandler onStartChild(String namespace,
                                     String localName,
                                     String prefix,
                                     Attributes attributes,
                                     DeserializationContext context)
...
                // Only deserialize this way if there is a unique operation
                // for this QName.  If there are overloads,
                // we'll need to start recording.  If we're making a high-
                // fidelity recording anyway, don't bother (for now).
                if (msgContext != null && !msgContext.isHighFidelity() &&
                        (operations == null || operations.length == 1)) {
                    ((RPCElement)element).setNeedDeser(false);
                    handler = new RPCHandler((RPCElement)element, false);                // *** Hard coded false seems wrong to me
                    if (operations != null) {
                        ((RPCHandler)handler).setOperation(operations[0]);
                        msgContext.setOperation(operations[0]);
                    }
                }
The 2nd argument to the RPCHandler() constructor is named "isResponse"
 
    public RPCHandler(RPCElement rpcElem, boolean isResponse)

 
It seems wrong to me that this should be hard-coded to false.  It appears that this code is (also) used when deserializing the response from the server.  Since the RPCHandler class uses the "isResponse" flag to determine what the type should be, this explains why my Axis client code is incorrectly thinking the return value is the same type as my first request parameter.
 
Also, the test for msgContext.isHighFidelity() explains why streaming needs to be in effect for this issue to arise.
 
As a quick test, I changed this to "true", and my Axis client application worked fine.  However, this can't be the right fix, since I suppose that this same code is used to deserialize the request message on the server side.
 
I noted that the one other call to the RPCHandler constructor determined the value of isResponse as follows.
 
        boolean isResponse = ((msg != null) &&
                              Message.RESPONSE.equals(msg.getMessageType()));
 
        // We're going to need this below, so create one.
        RPCHandler rpcHandler = new RPCHandler(this, isResponse);
Hopefully, this is coherent.
 
Regards,
 
Jeremy
This email may contain material that is confidential, privileged and/or attorney work product for the sole use of the intended recipient. Any review, reliance or distribution by others or forwarding without express permission is strictly prohibited. If you are not the intended recipient, please contact the sender and delete all copies.

Reply via email to