[ 
https://issues.apache.org/jira/browse/AXIS-2880?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13659305#comment-13659305
 ] 

Bhupendra commented on AXIS-2880:
---------------------------------

Hi,

Could you please point out the exact code change which needs to be done to fix 
the problem pointed by you. Here is the constructor snippet which I am seeing 
in the generated stub class for me.

public ChargingFacadeEndpointBindingStub() throws AxisFault
  {
    this(null);
  }

  public ChargingFacadeEndpointBindingStub(URL endpointURL, 
javax.xml.rpc.Service service) throws AxisFault {
    this(service);
    this.cachedEndpoint = endpointURL;
  }

  public ChargingFacadeEndpointBindingStub(javax.xml.rpc.Service service) 
throws AxisFault {
    if (service == null)
      this.service = new org.apache.axis.client.Service();
    else {
      this.service = service;
    }

I am running into thread-safety issues when multiple threads invoke this stub 
in my product so if you could help me out figuring out the problem and if there 
is any fix/patch which is already present and I could simply apply that to 
resolve my problem?

Thanks,
Bhupendra.
                
> Type mappings should be registered in the locator instead of the stub
> ---------------------------------------------------------------------
>
>                 Key: AXIS-2880
>                 URL: https://issues.apache.org/jira/browse/AXIS-2880
>             Project: Axis
>          Issue Type: Bug
>          Components: Basic Architecture
>    Affects Versions: 1.4
>            Reporter: Andreas Veithen
>            Assignee: Andreas Veithen
>             Fix For: 1.4.1
>
>
> The createCall method in a generated stub contains the following code:
> // 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);
>         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.Object x = cachedSerFactories.get(i);
>             if (x instanceof Class) {
>                 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);
>             }
>             else if (x instanceof javax.xml.rpc.encoding.SerializerFactory) {
>                 org.apache.axis.encoding.SerializerFactory sf = 
> (org.apache.axis.encoding.SerializerFactory)
>                      cachedSerFactories.get(i);
>                 org.apache.axis.encoding.DeserializerFactory df = 
> (org.apache.axis.encoding.DeserializerFactory)
>                      cachedDeserFactories.get(i);
>                 _call.registerTypeMapping(cls, qName, sf, df, false);
>             }
>         }
>     }
> }
> As noted in the comment, the type mapping is actually registered in the type 
> mapping registry of the service (implemented by the locator). This raises the 
> question why that registration is not done in the locator in the first place. 
> In fact, doing the registration before the first call in the stub has a 
> couple of issues:
> * This is prone to concurrency issues as described in AXIS-2498.
> * It unnecessarily increases the cost of creating a stub. Note that each stub 
> will actually attempt to perform the registration, but only the first one 
> will effectively modify the type mappings. Execution of the code shown above 
> by subsequently created stubs (from the same locator) will be a no-op because 
> the type mappings are already registered (and registerTypeMapping will 
> silently skip the registration).
> * If the service has multiple ports, then the code (in the stub constructor) 
> that initializes the cachedSerClasses, cachedSerQNames, cachedSerFactories 
> and cachedDeserFactories fields is actually duplicated in each stub because 
> the same type mappings are registered in each stub (although with potentially 
> different encoding styles).
> Note that if the code generator is changed so that type mappings are 
> registered in the locator, then the constructors of the stubs need to be 
> changed:
> public XxxStub() throws org.apache.axis.AxisFault {
>      this(null);
> }
> public XxxStub(java.net.URL endpointURL, javax.xml.rpc.Service service) 
> throws org.apache.axis.AxisFault {
>      this(service);
>      super.cachedEndpoint = endpointURL;
> }
> public XxxStub(javax.xml.rpc.Service service) throws 
> org.apache.axis.AxisFault {
>     if (service == null) {
>         super.service = new org.apache.axis.client.Service();
>     } else {
>         super.service = service;
>     }
>     ...
> }
> Instead of creating a plain org.apache.axis.client.Service instance, the code 
> should create an instance of the locator. Note that this would still make a 
> difference for application code that directly creates a stub and passes a 
> reference to a Service that is not an instance of the locator. However, this 
> is a very unlikely scenario.

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to