Return-Path: Delivered-To: apmail-ws-axis-user-archive@www.apache.org Received: (qmail 88816 invoked from network); 10 Jun 2004 15:02:43 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur-2.apache.org with SMTP; 10 Jun 2004 15:02:43 -0000 Received: (qmail 76106 invoked by uid 500); 10 Jun 2004 15:02:27 -0000 Delivered-To: apmail-ws-axis-user-archive@ws.apache.org Received: (qmail 76085 invoked by uid 500); 10 Jun 2004 15:02:27 -0000 Mailing-List: contact axis-user-help@ws.apache.org; run by ezmlm Precedence: bulk Reply-To: axis-user@ws.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list axis-user@ws.apache.org Received: (qmail 76057 invoked by uid 99); 10 Jun 2004 15:02:27 -0000 Received: from [64.224.219.83] (HELO mail9.atl.registeredsite.com) (64.224.219.83) by apache.org (qpsmtpd/0.27.1) with ESMTP; Thu, 10 Jun 2004 08:02:27 -0700 Received: from imta01a2.registeredsite.com (imta01a2.registeredsite.com [64.225.255.10]) by mail9.atl.registeredsite.com (8.12.11/8.12.8) with ESMTP id i5AF2D5l032020 for ; Thu, 10 Jun 2004 15:02:14 GMT Received: from BORON ([207.172.210.11]) by imta01a2.registeredsite.com with SMTP id <20040610150209.TJKG4075.imta01a2.registeredsite.com@BORON> for ; Thu, 10 Jun 2004 11:02:09 -0400 From: "Cameron F. Logan" To: Subject: RE: TypeMappingRegistry getting "lost" during call Date: Thu, 10 Jun 2004 11:00:22 -0400 Message-ID: MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="----=_NextPart_000_0026_01C44EDA.2070D8C0" X-Priority: 3 (Normal) X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook IMO, Build 9.0.6604 (9.0.2911.0) Importance: Normal X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1409 In-Reply-To: X-Virus-Checked: Checked X-Spam-Rating: minotaur-2.apache.org 1.6.2 0/1000/N This is a multi-part message in MIME format. ------=_NextPart_000_0026_01C44EDA.2070D8C0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit 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 ================== 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(): // 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, ================== 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 ------=_NextPart_000_0026_01C44EDA.2070D8C0 Content-Type: text/html; charset="us-ascii" Content-Transfer-Encoding: quoted-printable
Hi Everyone:
 
I actually discovered the cause of my problem, and = searching=20 through this list's archives, I believe the same solution would apply to = many=20 others who have experienced similar issues. In the end, the solution was = so=20 simple that I'm almost embarrassed to post it = here.
 
The problem had nothing to do with Castor = (de)serialization=20 or the AxisClient class. The problem lie in the fact that I was using a=20 ClientHandler to support WSSE [http://axis-wsse.sourceforge.net/]. = Nevertheless,=20 the ClientHandler itself was not the problem (in fact, I highly = recommend it for=20 simple Username/Password WSSE support). It was the fact that=20 the "setClientHandlers" method was called that was the problem. = This member=20 of the org.apache.axis.client.Call class ends up calling its = sibling=20 member "setSOAPService" with a new SOAPService = object. The=20 SOAPService object is set as a private member of the Call object = [with a=20 variable name of "myService"].
 
This is all fine until the Call.invoke() method is = executed=20 by the SoapStub. It is within the logic of this method that "myService" = is set=20 to the MessageContext object. NOW THE PROBLEM BEGINS, for it is within = the=20 "setService" member of the MessageContext object that the = MessageContext's=20 encoding type is set to SOAP encoding. Since the service was using = SOAP=20 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=20 was generated by WSDL2Java, we see that the encoding under which = the=20 TypeMappingRegistry was created was "null". The TypeMappingRegistry = that=20 had been created is no longer visible to objects that are=20 now attempting to retrieve TypeMappings for the SOAP1_1=20 encoding.
 
Perhaps it should have been obvious to me that I = would have=20 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=20 following line in the "createCall" member of the=20 SoapStub from:
 
_call.setEncodingStyle(null);=
 
to:
 
 _call.setEncodingStyle(org.apache.axis.soap.SOAPConstants.= SOAP11_CONSTANTS.getEncodingURI());
 
 
 
AXIS=20 v1.2beta code snippets shown to=20 illustrate
 
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
<WSDL2Java-Generated>SoapStub.createCall():<= /DIV>
 
=
    private = org.apache.axis.client.Call=20 createCall() throws java.rmi.RemoteException=20 {
        try=20 {
           =20 org.apache.axis.client.Call _call=20 =3D
           =         =20 (org.apache.axis.client.Call)=20 super.service.createCall();
       =     =20 if (super.maintainSessionSet)=20 {
           &n= bsp;   =20 _call.setMaintainSession(super.maintainSession);
   &nb= sp;       =20 }
            = if=20 (super.cachedUsername !=3D null)=20 {
           &n= bsp;   =20 _call.setUsername(super.cachedUsername);
     = ;      =20 }
            = if=20 (super.cachedPassword !=3D null)=20 {
           &n= bsp;   =20 _call.setPassword(super.cachedPassword);
     = ;      =20 }
            = if=20 (super.cachedEndpoint !=3D null)=20 {
           &n= bsp;   =20 _call.setTargetEndpointAddress(super.cachedEndpoint);
  &nbs= p;        =20 }
            = if=20 (super.cachedTimeout !=3D null)=20 {
           &n= bsp;   =20 _call.setTimeout(super.cachedTimeout);
     &= nbsp;     =20 }
            = if=20 (super.cachedPortName !=3D null)=20 {
           &n= bsp;   =20 _call.setPortName(super.cachedPortName);
     = ;      =20 }
           =20 java.util.Enumeration keys =3D=20 super.cachedProperties.keys();
      &nb= sp;    =20 while (keys.hasMoreElements())=20 {
           &n= bsp;   =20 java.lang.String key =3D (java.lang.String)=20 keys.nextElement();
        &n= bsp;      =20 _call.setProperty(key,=20 super.cachedProperties.get(key));
      =      =20 }
 
   // ***Added for WSSE=20 support***
   _call.setProperty(WsseClientHandler.PASSW= ORD_OPTION,=20 WsseClientHandler.PASSWORD_CLEARTEXT);
   _call.setClie= ntHandlers(new=20 WsseClientHandler(), null);
 
           =20 // All the type mapping information is=20 registered
          = ; =20 // when the first call is=20 made.
          &nbs= p; //=20 The type mapping information is actually registered=20 in
            = // the=20 TypeMappingRegistry of the service,=20 which
          &nbs= p; //=20 is the reason why registration is only needed for the first=20 call.
          &nbs= p;=20 synchronized (this)=20 {
           &n= bsp;   =20 if (firstCall())=20 {
           &n= bsp;       =20 // must set encoding style before registering=20 serializers
         &nbs= p;         =20 _call.setEncodingStyle(null); <=3D=3D=3D Encoding under which=20 TypeMappingRegistry=20 gets indexed
        &nbs= p;          =20 for (int i =3D 0; i < cachedSerFactories.size(); ++i)=20 {
           &n= bsp;           =20 java.lang.Class cls =3D (java.lang.Class)=20 cachedSerClasses.get(i);
       &nb= sp;           &nbs= p;   =20 javax.xml.namespace.QName qName=20 =3D
           =             &= nbsp;       =20 (javax.xml.namespace.QName)=20 cachedSerQNames.get(i);
       &nbs= p;            = ;   =20 java.lang.Class sf =3D=20 (java.lang.Class)
        &nbs= p;            = ;           =20 cachedSerFactories.get(i);
       &= nbsp;           &n= bsp;   =20 java.lang.Class df =3D=20 (java.lang.Class)
        &nbs= p;            = ;           =20 cachedDeserFactories.get(i);
       = ;            =     =20 _call.registerTypeMapping(cls, qName, sf, df,=20 false);
          &n= bsp;        =20 }
           &n= bsp;   =20 }
           =20 }
            = return=20 _call;
       =20 }
        catch = (java.lang.Throwable _t)=20 {
            = throw=20 new org.apache.axis.AxisFault("Failure trying to get the Call object",=20 _t);
        = }
   =20 }
 =20
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Call.setClientHandlers(Handler, Handler:
 
    = public void=20 setClientHandlers(Handler reqHandler, Handler = respHandler)
   =20 {
        // Create a SOAPService = which=20 will be used as the client-side=20 service
        //=20 handler.
        = setSOAPService(new=20 SOAPService(reqHandler, null, respHandler)); <=3D=3D=3D new=20 SOAPService
    }
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Call.setSOAPService(SOAPService):
 
    public void setSOAPService(SOAPService=20 service)
    = {
       =20 myService =3D service; <=3D=3D=3D myService gets set in = the Call=20 object
        if (service !=3D = null)=20 {
            = // Set=20 the service so that it defers missing property gets to=20 the
           = //=20 Call.  So when client-side Handlers get at the=20 MessageContext,
         =   =20 // the property scoping will be MC -> SOAPService -> Call ->=20 Engine
          &nb= sp;=20
            = // THE=20 ORDER OF THESE TWO CALLS IS IMPORTANT, since setting=20 the
           = //=20 engine on a service will set the property parent for the=20 service
          &n= bsp;=20 service.setEngine(this.service.getAxisClient());
   &nb= sp;       =20 service.setPropertyParent(myProperties);
     = ;  =20 }
    }
 
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
Call.invoke():
 
<snip>
        // = Determine=20 client target service
        if=20 (myService !=3D null) { <=3D=3D=3D = myService is not=20 null; it was automatically set when setClientHandlers was=20 called
         &n= bsp; =20 // If we have a SOAPService kicking around, use that=20 directly
          &= nbsp;=20 msgContext.setService(myService); <=3D=3D=3DSOAPService set in=20 MessageContext
        } else=20 {
            = if=20 (portName !=3D null)=20 {
           &n= bsp;   =20 // No explicit service.  If we have a target service=20 name,
<snip>
 
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
MessageContext.setService(SOAPService):
 
    public void setService(SOAPService sh) = throws=20 AxisFault
    = {
       =20 log.debug("MessageContext:=20 setServiceHandler("+sh+")");
       = ;=20 serviceHandler =3D sh;
        if = (sh !=3D=20 null) = {
           =20 targetService =3D=20 sh.getName();
         &n= bsp; =20 SOAPService service =3D=20 sh;
           = =20 TypeMappingRegistry tmr =3D=20 service.getTypeMappingRegistry();
      =      =20 setTypeMappingRegistry(tmr);
 
          &nbs= p; //=20 styles are not "soap version aware" so=20 compensate...
         &n= bsp; =20 setEncodingStyle(service.getUse().getEncoding()); <=3D=3D=3D Encoding = style=20 updated
 
          &nbs= p; //=20 This MessageContext should now defer properties it can't=20 find
           = ; // to=20 the Service's=20 options.
          &= nbsp;=20 bag.setParent(sh.getOptions());
 
          &nbs= p; //=20 Note that we need (or don't need) high-fidelity SAX=20 recording
          =  =20 // of deserialized messages according to the setting on=20 the
           = // new=20 service.
          &= nbsp;=20 highFidelity =3D = service.needsHighFidelityRecording();
 
          &nbs= p;=20 service.getInitializedServiceDesc(this);
     = ;  =20 }
    }
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
 
 
-----Original Message-----
From: Jana Poornavel=20 [mailto:jpoornavel@orangescape.com]
Sent: Thursday, June 10, = 2004=20 12:59 AM
To: axis-user@ws.apache.org
Subject: RE:=20 TypeMappingRegistry getting "lost" during call

Hi=20 cameron,

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

Exist in your = classpath=20 ?

 

Regards,

jana

 

 

Janarthanan=20 Poornavel

www.OrangeScape.com

 


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

 

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

 

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

 

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

 

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

 

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

 

Thanks,

Cameron

______________________________
Cameron F.=20 Logan
Envisa

281 Pleasant=20 Street
Framingham, MA 01701
= tel:  = 508.405.1220=20 x112

 

------=_NextPart_000_0026_01C44EDA.2070D8C0--