You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by "Cameron F. Logan" <ca...@envisa.com> on 2004/06/09 18:42:34 UTC

TypeMappingRegistry getting "lost" during call

I am developing an Axis-Castor based client application for a series of .NET
web services using Axis v1.1 and Castor v0.9.5.3. I have built Axis using
the Castor libraries, so the CastorDeserializer is available to me. I have
used WSDL2Java to generate client proxies for the services. As per usual
with the WSDL2Java generated proxy code, the type mapping information is
loaded programmatically and I manually changed the BeanSerializer... entries
to CastorSerializer entries.

Still, I have been receiving a "Deserializer not found" error upon execution
of my client code and have painstakingly traced this down to a problem with
either the MessageContext or the TypeMappingRegistry being effectively reset
after the pivot. I can resolve the proper TypeMapping object for the each
given response message successfully until the code hits the AxisClient
class. Then the TypeMapping starts to resolve to null. I have tried included
the client-config.wsdd file as an alternate means of providing type mapping
information, but that yields the same error.

I know that this isn't a problem with the Axis/Castor integration because I
am able to avoid the error and make successful calls to the web services by
hard-coding the deserializer in the Call object to be the CastorDeserialzer.

Obviously, I do not want to hard code the deserializer this way, but so far
it is the only thing that has seemed to work.

Can anyone shed light on why or how the TypeMapping information is cleared
out half-way through the interaction with the web service? What could
possibly be wrong? I can provide oodles of code if necessary, but thought I
would start with the brief description of the problem. This is driving me
crazy!

Thanks,
Cameron
______________________________
Cameron F. Logan
Envisa
281 Pleasant Street
Framingham, MA 01701
tel:  508.405.1220 x112

Re: TypeMappingRegistry getting "lost" during call

Posted by Davanum Srinivas <da...@gmail.com>.
FYI, If you use http://axis-wsse.sourceforge.net/ you will not be able
to interoperate with latest WSE 2.0 Final or latest JWSDP (released a
few weeks back). You can use Apache WSS4J
(http://ws.apache.org/ws-fx/wss4j/) if to support latest OASIS Web
Services Security specifications.

-- dims

----- Original Message -----
From: Cameron F. Logan <ca...@envisa.com>
Date: Thu, 10 Jun 2004 11:00:22 -0400
Subject: RE: TypeMappingRegistry getting "lost" during call
To: axis-user@ws.apache.org









Hi Everyone:

 

I actually discovered the cause of my problem, and searching 
through this list's archives, I believe the same solution would apply to many 
others who have experienced similar issues. In the end, the solution was so 
simple that I'm almost embarrassed to post it here.

 

The problem had nothing to do with Castor (de)serialization 
or the AxisClient class. The problem lie in the fact that I was using a 
ClientHandler to support WSSE [http://axis-wsse.sourceforge.net/].
Nevertheless,
the ClientHandler itself was not the problem (in fact, I highly
recommend it for
simple Username/Password WSSE support). It was the fact that 
the "setClientHandlers" method was called that was the problem. This member 
of the org.apache.axis.client.Call class ends up calling its sibling 
member "setSOAPService" with a new SOAPService object. The 
SOAPService object is set as a private member of the Call object [with a 
variable name of "myService"].

 

This is all fine until the Call.invoke() method is executed 
by the SoapStub. It is within the logic of this method that "myService" is set 
to the MessageContext object. NOW THE PROBLEM BEGINS, for it is within the 
"setService" member of the MessageContext object that the MessageContext's 
encoding type is set to SOAP encoding. Since the service was using SOAP 
v1.1, the actual value of the encoding became:
"http://schemas.xmlsoap.org/soap/encoding/". However, if we refer back
to the SoapStub object that
was generated by WSDL2Java, we see that the encoding under which the 
TypeMappingRegistry was created was "null". The TypeMappingRegistry that 
had been created is no longer visible to objects that are 
now attempting to retrieve TypeMappings for the SOAP1_1 
encoding.

 

Perhaps it should have been obvious to me that I would have 
to edit the encoding within the SoapStub object simply because I added a 
ClientHandler, but it was not. Regardless, the solution was to change the 
following line in the "createCall" member of the 
SoapStub from:

 

_call.setEncodingStyle(null);

 

to:

 

 _call.setEncodingStyle(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS.getEncodingURI());

 

 

 

AXIS 
v1.2beta code snippets shown to 
illustrate

 


==================

<WSDL2Java-Generated>SoapStub.createCall():

 

    private org.apache.axis.client.Call 
createCall() throws java.rmi.RemoteException 
{
        try 
{
            
org.apache.axis.client.Call _call 
=
                    
(org.apache.axis.client.Call) 
super.service.createCall();
            
if (super.maintainSessionSet) 
{
                
_call.setMaintainSession(super.maintainSession);
            
}
            if 
(super.cachedUsername != null) 
{
                
_call.setUsername(super.cachedUsername);
            
}
            if 
(super.cachedPassword != null) 
{
                
_call.setPassword(super.cachedPassword);
            
}
            if 
(super.cachedEndpoint != null) 
{
                
_call.setTargetEndpointAddress(super.cachedEndpoint);
            
}
            if 
(super.cachedTimeout != null) 
{
                
_call.setTimeout(super.cachedTimeout);
            
}
            if 
(super.cachedPortName != null) 
{
                
_call.setPortName(super.cachedPortName);
            
}
            
java.util.Enumeration keys = 
super.cachedProperties.keys();
            
while (keys.hasMoreElements()) 
{
                
java.lang.String key = (java.lang.String) 
keys.nextElement();
                
_call.setProperty(key, 
super.cachedProperties.get(key));
            
}

 
   // ***Added for WSSE 
support***
   _call.setProperty(WsseClientHandler.PASSWORD_OPTION, 
WsseClientHandler.PASSWORD_CLEARTEXT);
   _call.setClientHandlers(new 
WsseClientHandler(), null);

 
            
// All the type mapping information is 
registered
            
// when the first call is 
made.
            // 
The type mapping information is actually registered 
in
            // the 
TypeMappingRegistry of the service, 
which
            // 
is the reason why registration is only needed for the first 
call.
            
synchronized (this) 
{
                
if (firstCall()) 
{
                    
// must set encoding style before registering 
serializers
                    
_call.setEncodingStyle(null); <=== Encoding under which 
TypeMappingRegistry 
gets indexed
                    
for (int i = 0; i < cachedSerFactories.size(); ++i) 
{
                        
java.lang.Class cls = (java.lang.Class) 
cachedSerClasses.get(i);
                        
javax.xml.namespace.QName qName 
=
                                
(javax.xml.namespace.QName) 
cachedSerQNames.get(i);
                        
java.lang.Class sf = 
(java.lang.Class)
                                 
cachedSerFactories.get(i);
                        
java.lang.Class df = 
(java.lang.Class)
                                 
cachedDeserFactories.get(i);
                        
_call.registerTypeMapping(cls, qName, sf, df, 
false);
                    
}
                
}
            
}
            return 
_call;
        
}
        catch (java.lang.Throwable _t) 
{
            throw 
new org.apache.axis.AxisFault("Failure trying to get the Call object", 
_t);
        }
    
}



  

==================

Call.setClientHandlers(Handler, Handler:

     public void 
setClientHandlers(Handler reqHandler, Handler respHandler)
    
{
        // Create a SOAPService which 
will be used as the client-side 
service
        // 
handler.
        setSOAPService(new 
SOAPService(reqHandler, null, respHandler)); <=== new 
SOAPService
    }


==================

Call.setSOAPService(SOAPService):

 

    public void setSOAPService(SOAPService 
service)
    {
        
myService = service; <=== myService gets set in the Call 
object
        if (service != null) 
{
            // Set 
the service so that it defers missing property gets to 
the
            // 
Call.  So when client-side Handlers get at the 
MessageContext,
            
// the property scoping will be MC -> SOAPService -> Call -> 
Engine
            

            // THE 
ORDER OF THESE TWO CALLS IS IMPORTANT, since setting 
the
            // 
engine on a service will set the property parent for the 
service
            
service.setEngine(this.service.getAxisClient());
            
service.setPropertyParent(myProperties);
        
}
    }

 

==================

Call.invoke():

 

<snip>
        // Determine 
client target service
        if 
(myService != null) { <=== myService is not 
null; it was automatically set when setClientHandlers was 
called
            
// If we have a SOAPService kicking around, use that 
directly
            
msgContext.setService(myService); <===SOAPService set in 
MessageContext
        } else 
{
            if 
(portName != null) 
{
                
// No explicit service.  If we have a target service 
name,
<snip>

 

==================

MessageContext.setService(SOAPService):

 

    public void setService(SOAPService sh) throws 
AxisFault
    {
        
log.debug("MessageContext: 
setServiceHandler("+sh+")");
        
serviceHandler = sh;
        if (sh != 
null) {
            
targetService = 
sh.getName();
            
SOAPService service = 
sh;
            
TypeMappingRegistry tmr = 
service.getTypeMappingRegistry();
            
setTypeMappingRegistry(tmr);

 
            // 
styles are not "soap version aware" so 
compensate...
            
setEncodingStyle(service.getUse().getEncoding()); <=== Encoding style 
updated

 
            // 
This MessageContext should now defer properties it can't 
find
            // to 
the Service's 
options.
            
bag.setParent(sh.getOptions());

 
            // 
Note that we need (or don't need) high-fidelity SAX 
recording
            
// of deserialized messages according to the setting on 
the
            // new 
service.
            
highFidelity = service.needsHighFidelityRecording();

 
            
service.getInitializedServiceDesc(this);
        
}
    }

==================


 

 

-----Original Message-----
From: Jana Poornavel 
[mailto:jpoornavel@orangescape.com]
Sent: Thursday, June 10, 2004 
12:59 AM
To: axis-user@ws.apache.org
Subject: RE: 
TypeMappingRegistry getting "lost" during call






Hi 
cameron,


                  
How do you load your Deserializing classes? Or let me put it this way,does your 
serializer


Exist in your classpath 
?


 


Regards,


jana


 




 


Janarthanan 
Poornavel


www.OrangeScape.com


 



________________________________




From: Cameron 
F. Logan [mailto:cameron.logan@envisa.com] 
Sent: Wednesday, June 09, 2004 10:13 
PM
To: axis-user@ws.apache.org
Subject: TypeMappingRegistry getting "lost" 
during call


 




I am developing an Axis-Castor based 
client application for a series of .NET web services using Axis v1.1 and Castor 
v0.9.5.3. I have built Axis using the Castor libraries, so the 
CastorDeserializer is available to me. I have used WSDL2Java to generate client 
proxies for the services. As per usual with the WSDL2Java generated proxy 
code, the type mapping information is loaded programmatically and I manually 
changed the BeanSerializer... entries to CastorSerializer 
entries.




 




Still, I have been 
receiving a "Deserializer not found" error upon execution of my client code 
and have painstakingly traced this down to a problem with either the 
MessageContext or the TypeMappingRegistry being effectively reset after the 
pivot. I can resolve the proper TypeMapping object for the each given response 
message successfully until the code hits the AxisClient class. Then the 
TypeMapping starts to resolve to null. I have tried included the 
client-config.wsdd file as an alternate means of providing type mapping 
information, but that yields the same error.




 




I know that this isn't a problem 
with the Axis/Castor integration because I am able to avoid the error and make 
successful calls to the web services by hard-coding the deserializer
in the Call
object to be the CastorDeserialzer.




 




Obviously, I do not want to hard 
code the deserializer this way, but so far it is the only thing that has seemed 
to work.




 




Can anyone shed light on why or how 
the TypeMapping information is cleared out half-way through the
interaction with
the web service? What could possibly be wrong? I can provide oodles of code if 
necessary, but thought I would start with the brief description of the problem. 
This is driving me crazy!




 




Thanks,




Cameron




______________________________
Cameron F. 
Logan
Envisa
281 Pleasant 
Street
Framingham, MA 01701
tel:  508.405.1220 
x112




 



-- 
Davanum Srinivas - http://webservices.apache.org/~dims/

RE: TypeMappingRegistry getting "lost" during call

Posted by "Cameron F. Logan" <ca...@envisa.com>.
Hi Everyone:

I actually discovered the cause of my problem, and searching through this
list's archives, I believe the same solution would apply to many others who
have experienced similar issues. In the end, the solution was so simple that
I'm almost embarrassed to post it here.

The problem had nothing to do with Castor (de)serialization or the
AxisClient class. The problem lie in the fact that I was using a
ClientHandler to support WSSE [http://axis-wsse.sourceforge.net/].
Nevertheless, the ClientHandler itself was not the problem (in fact, I
highly recommend it for simple Username/Password WSSE support). It was the
fact that the "setClientHandlers" method was called that was the problem.
This member of the org.apache.axis.client.Call class ends up calling its
sibling member "setSOAPService" with a new SOAPService object. The
SOAPService object is set as a private member of the Call object [with a
variable name of "myService"].

This is all fine until the Call.invoke() method is executed by the SoapStub.
It is within the logic of this method that "myService" is set to the
MessageContext object. NOW THE PROBLEM BEGINS, for it is within the
"setService" member of the MessageContext object that the MessageContext's
encoding type is set to SOAP encoding. Since the service was using SOAP
v1.1, the actual value of the encoding became:
"http://schemas.xmlsoap.org/soap/encoding/". However, if we refer back to
the SoapStub object that was generated by WSDL2Java, we see that the
encoding under which the TypeMappingRegistry was created was "null". The
TypeMappingRegistry that had been created is no longer visible to objects
that are now attempting to retrieve TypeMappings for the SOAP1_1 encoding.

Perhaps it should have been obvious to me that I would have to edit the
encoding within the SoapStub object simply because I added a ClientHandler,
but it was not. Regardless, the solution was to change the following line in
the "createCall" member of the SoapStub from:

_call.setEncodingStyle(null);

to:


_call.setEncodingStyle(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS.g
etEncodingURI());



AXIS v1.2beta code snippets shown to illustrate

==================
<WSDL2Java-Generated>SoapStub.createCall():

    private org.apache.axis.client.Call createCall() throws
java.rmi.RemoteException {
        try {
            org.apache.axis.client.Call _call =
                    (org.apache.axis.client.Call)
super.service.createCall();
            if (super.maintainSessionSet) {
                _call.setMaintainSession(super.maintainSession);
            }
            if (super.cachedUsername != null) {
                _call.setUsername(super.cachedUsername);
            }
            if (super.cachedPassword != null) {
                _call.setPassword(super.cachedPassword);
            }
            if (super.cachedEndpoint != null) {
                _call.setTargetEndpointAddress(super.cachedEndpoint);
            }
            if (super.cachedTimeout != null) {
                _call.setTimeout(super.cachedTimeout);
            }
            if (super.cachedPortName != null) {
                _call.setPortName(super.cachedPortName);
            }
            java.util.Enumeration keys = super.cachedProperties.keys();
            while (keys.hasMoreElements()) {
                java.lang.String key = (java.lang.String)
keys.nextElement();
                _call.setProperty(key, super.cachedProperties.get(key));
            }

   // ***Added for WSSE support***
   _call.setProperty(WsseClientHandler.PASSWORD_OPTION,
WsseClientHandler.PASSWORD_CLEARTEXT);
   _call.setClientHandlers(new WsseClientHandler(), null);

            // All the type mapping information is registered
            // when the first call is made.
            // The type mapping information is actually registered in
            // the TypeMappingRegistry of the service, which
            // is the reason why registration is only needed for the first
call.
            synchronized (this) {
                if (firstCall()) {
                    // must set encoding style before registering
serializers
                    _call.setEncodingStyle(null); <=== Encoding under which
TypeMappingRegistry gets indexed
                    for (int i = 0; i < cachedSerFactories.size(); ++i) {
                        java.lang.Class cls = (java.lang.Class)
cachedSerClasses.get(i);
                        javax.xml.namespace.QName qName =
                                (javax.xml.namespace.QName)
cachedSerQNames.get(i);
                        java.lang.Class sf = (java.lang.Class)
                                 cachedSerFactories.get(i);
                        java.lang.Class df = (java.lang.Class)
                                 cachedDeserFactories.get(i);
                        _call.registerTypeMapping(cls, qName, sf, df,
false);
                    }
                }
            }
            return _call;
        }
        catch (java.lang.Throwable _t) {
            throw new org.apache.axis.AxisFault("Failure trying to get the
Call object", _t);
        }
    }

==================
Call.setClientHandlers(Handler, Handler:

    public void setClientHandlers(Handler reqHandler, Handler respHandler)
    {
        // Create a SOAPService which will be used as the client-side
service
        // handler.
        setSOAPService(new SOAPService(reqHandler, null, respHandler)); <===
new SOAPService
    }

==================
Call.setSOAPService(SOAPService):

    public void setSOAPService(SOAPService service)
    {
        myService = service; <=== myService gets set in the Call object
        if (service != null) {
            // Set the service so that it defers missing property gets to
the
            // Call.  So when client-side Handlers get at the
MessageContext,
            // the property scoping will be MC -> SOAPService -> Call ->
Engine

            // THE ORDER OF THESE TWO CALLS IS IMPORTANT, since setting the
            // engine on a service will set the property parent for the
service
            service.setEngine(this.service.getAxisClient());
            service.setPropertyParent(myProperties);
        }
    }

==================
Call.invoke():

<snip>
        // Determine client target service
        if (myService != null) { <=== myService is not null; it was
automatically set when setClientHandlers was called
            // If we have a SOAPService kicking around, use that directly
            msgContext.setService(myService); <===SOAPService set in
MessageContext
        } else {
            if (portName != null) {
                // No explicit service.  If we have a target service name,
<snip>

==================
MessageContext.setService(SOAPService):

    public void setService(SOAPService sh) throws AxisFault
    {
        log.debug("MessageContext: setServiceHandler("+sh+")");
        serviceHandler = sh;
        if (sh != null) {
            targetService = sh.getName();
            SOAPService service = sh;
            TypeMappingRegistry tmr = service.getTypeMappingRegistry();
            setTypeMappingRegistry(tmr);

            // styles are not "soap version aware" so compensate...
            setEncodingStyle(service.getUse().getEncoding()); <=== Encoding
style updated

            // This MessageContext should now defer properties it can't find
            // to the Service's options.
            bag.setParent(sh.getOptions());

            // Note that we need (or don't need) high-fidelity SAX recording
            // of deserialized messages according to the setting on the
            // new service.
            highFidelity = service.needsHighFidelityRecording();

            service.getInitializedServiceDesc(this);
        }
    }
==================



-----Original Message-----
From: Jana Poornavel [mailto:jpoornavel@orangescape.com]
Sent: Thursday, June 10, 2004 12:59 AM
To: axis-user@ws.apache.org
Subject: RE: TypeMappingRegistry getting "lost" during call


Hi cameron,

                  How do you load your Deserializing classes? Or let me put
it this way,does your serializer

Exist in your classpath ?



Regards,

jana





Janarthanan Poornavel

www.OrangeScape.com




----------------------------------------------------------------------------
----

From: Cameron F. Logan [mailto:cameron.logan@envisa.com]
Sent: Wednesday, June 09, 2004 10:13 PM
To: axis-user@ws.apache.org
Subject: TypeMappingRegistry getting "lost" during call



I am developing an Axis-Castor based client application for a series of .NET
web services using Axis v1.1 and Castor v0.9.5.3. I have built Axis using
the Castor libraries, so the CastorDeserializer is available to me. I have
used WSDL2Java to generate client proxies for the services. As per usual
with the WSDL2Java generated proxy code, the type mapping information is
loaded programmatically and I manually changed the BeanSerializer... entries
to CastorSerializer entries.



Still, I have been receiving a "Deserializer not found" error upon execution
of my client code and have painstakingly traced this down to a problem with
either the MessageContext or the TypeMappingRegistry being effectively reset
after the pivot. I can resolve the proper TypeMapping object for the each
given response message successfully until the code hits the AxisClient
class. Then the TypeMapping starts to resolve to null. I have tried included
the client-config.wsdd file as an alternate means of providing type mapping
information, but that yields the same error.



I know that this isn't a problem with the Axis/Castor integration because I
am able to avoid the error and make successful calls to the web services by
hard-coding the deserializer in the Call object to be the CastorDeserialzer.



Obviously, I do not want to hard code the deserializer this way, but so far
it is the only thing that has seemed to work.



Can anyone shed light on why or how the TypeMapping information is cleared
out half-way through the interaction with the web service? What could
possibly be wrong? I can provide oodles of code if necessary, but thought I
would start with the brief description of the problem. This is driving me
crazy!



Thanks,

Cameron

______________________________
Cameron F. Logan
Envisa
281 Pleasant Street
Framingham, MA 01701
tel:  508.405.1220 x112



RE: TypeMappingRegistry getting "lost" during call

Posted by Jana Poornavel <jp...@orangescape.com>.
Hi cameron,

                  How do you load your Deserializing classes? Or let me put
it this way,does your serializer

Exist in your classpath ?

 

Regards,

jana

 

 

Janarthanan Poornavel

www.OrangeScape.com

 

  _____  

From: Cameron F. Logan [mailto:cameron.logan@envisa.com] 
Sent: Wednesday, June 09, 2004 10:13 PM
To: axis-user@ws.apache.org
Subject: TypeMappingRegistry getting "lost" during call

 

I am developing an Axis-Castor based client application for a series of .NET
web services using Axis v1.1 and Castor v0.9.5.3. I have built Axis using
the Castor libraries, so the CastorDeserializer is available to me. I have
used WSDL2Java to generate client proxies for the services. As per usual
with the WSDL2Java generated proxy code, the type mapping information is
loaded programmatically and I manually changed the BeanSerializer... entries
to CastorSerializer entries.

 

Still, I have been receiving a "Deserializer not found" error upon execution
of my client code and have painstakingly traced this down to a problem with
either the MessageContext or the TypeMappingRegistry being effectively reset
after the pivot. I can resolve the proper TypeMapping object for the each
given response message successfully until the code hits the AxisClient
class. Then the TypeMapping starts to resolve to null. I have tried included
the client-config.wsdd file as an alternate means of providing type mapping
information, but that yields the same error.

 

I know that this isn't a problem with the Axis/Castor integration because I
am able to avoid the error and make successful calls to the web services by
hard-coding the deserializer in the Call object to be the CastorDeserialzer.

 

Obviously, I do not want to hard code the deserializer this way, but so far
it is the only thing that has seemed to work.

 

Can anyone shed light on why or how the TypeMapping information is cleared
out half-way through the interaction with the web service? What could
possibly be wrong? I can provide oodles of code if necessary, but thought I
would start with the brief description of the problem. This is driving me
crazy!

 

Thanks,

Cameron

______________________________
Cameron F. Logan
Envisa
281 Pleasant Street
Framingham, MA 01701
tel:  508.405.1220 x112