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

Andreas Veithen commented on AXIS-2498:
---------------------------------------

Using synchronized maps in TypeMappingImpl as proposed by Cyrille Le Clerc may 
have an undesired impact on performance. In addition it misses the root cause 
of the issue, which can be found in the generated code in the createCall method 
of the stub:

// 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, although the code calls registerTypeMapping on the 
Call object, the type mappings are actually registered in the service. On the 
other hand, the code synchronizes on the stub instance. If multiple stub 
instances created using the same service (locator) instance are used 
concurrently, then it is possible for multiple threads to enter the 
synchronized block and to attempt to modify the type mappings of the same 
service instance.

A quick fix could be to replace synchronized(this) by synchronized(service). 
However, as noted in AXIS-2880, it would be actually more natural to initialize 
the type mappings in the locator instead of the stub, and this would solve the 
concurrency issues once and for all.
                
> TypeMappingImpl is not thread safe
> ----------------------------------
>
>                 Key: AXIS-2498
>                 URL: https://issues.apache.org/jira/browse/AXIS-2498
>             Project: Axis
>          Issue Type: Bug
>          Components: Serialization/Deserialization
>    Affects Versions: 1.4
>            Reporter: Manuel Mall
>              Labels: thread-safety
>         Attachments: AXIS-2498.patch, Screenshot Eclipse Memory Analyzer 
> Hashmap.png, SynchronizedMap.java, TypeMappingImpl.java
>
>
> This issue originates from 
> http://marc.theaimsgroup.com/?l=axis-user&m=114993403032512&w=2.
> Original report and Cyrille's initial response below:
> ================================
>    Hello Manuel,
>    My understanding is the Stub#createCall invokes methods on an
> instance of TypeMapping that is shared by the AxisEngine via the
> TypeMappingRegistry. Unfortunately, this TypeMappingImpl is not
> threadsafe.
>    Here is a a draft patch that should fix it waiting for an official
> patch. Note that I didn't succeed in reproducing the deadlock, I
> patched according to my understanding of the problem.
>    Moreover, I preferred to send you this draft/emergency patch before
> doing extensive testings. It works on my samples but I didn't look at
> the impact on performances (it should be limited ).
> HOW TO US THIS PATCH ?
>    Here is a draft patch to fix this issue. To use it, the easiest way
> is to unzip axis-1.4-threadSafetyPatch.jar under /WEB-INF/classes
> (classloader order).
> PATCH DESCRIPTION
> TypeMappingImpl.java is the only modified class. Modifications:
> - use synchronized maps instead of plain HashMaps
> - synchronize internalRegister() method to ensure atomicity of access
> to maps in modification
> - synchronize access to "namespaces" variable in setSupportedEncodings
> to ensure atomicity of the clear-add sequence
>    Hope this helps,
>    Cyrille
> -- 
> Cyrille Le Clerc
> [email protected]
> [email protected]
> +33 6.61.33.69.86
> On 6/10/06, Manuel Mall <[email protected]> wrote:
> > I am aware that this topic has been discussed a number of times, e.g.
> > http://marc.theaimsgroup.com/?l=axis-user&m=113771126214607&w=2.
> >
> > I followed the advice that the locator is thread safe but the stub is
> > not and as I have only stateless calls I have therefore a single
> > instance of the serviceLocator and a new instance of the stub for each
> > call.
> >
> > However, when I have many simultaneous client calls I get
> > random "lock-ups" of the system. The threads always end up stuck in the
> > same state, that is in a call to HashMap.containsKey (see below). The
> > trace snippet is taken from a 'kill -3' output. There were around 20
> > threads all with the identical trace. The only difference being the
> > address in the '- locked <...> (a ...)' line, which is to be expected
> > as I have separate instances of the stub.
> >
> > I had hoped that the fix to
> > https://issues.apache.org/jira/browse/AXIS-2284 which is in Axis 1.4
> > had addressed this issue. But even after switching to Axis 1.4 the
> > problem remains. So it seems to me that there is another concurrent
> > HashMap modification problem left in the Axis code in the area of the
> > Type Mapping Registry.
> >
> > Needless to say that the problem only occurs on a multi CPU system.
> >
> > As I am really not familiar enough with the Axis internals I am
> > wondering if anyone with more insight has a suggestion how to avoid
> > this.
> >
> > Thanks
> >
> > Manuel
> > -----
> > "LandataWebPollRequestEventSlave:" prio=1 tid=0x8b48f0a0 nid=0x25cf
> > runnable [0x8ac74000..0x8ac745f0]
> > at java.util.HashMap.containsKey(HashMap.java:349)
> > at java.util.HashMap$KeySet.contains(HashMap.java:873)
> > at
> > org.apache.axis.encoding.TypeMappingImpl.isRegistered(TypeMappingImpl.java:195)
> > at
> > org.apache.axis.encoding.TypeMappingDelegate.isRegistered(TypeMappingDelegate.java:136)
> > at org.apache.axis.client.Call.registerTypeMapping(Call.java:2280)
> > at org.apache.axis.client.Call.registerTypeMapping(Call.java:2322)
> > at
> > au.com.anstat.oscar.landata.webservices.externalwsdl.Portal_340Stub.createCall(Portal_340Stub.java:2494)
> >         - locked <0x91cb2dc8> (a
> > au.com.anstat.oscar.landata.webservices.externalwsdl.Portal_340Stub)
> > at
> > au.com.anstat.oscar.landata.webservices.externalwsdl.Portal_340Stub.propertyCertificateList(Portal_340Stub.java:3979)
> > at
> > au.com.anstat.oscar.common.landata.Operation.doPropertyCertificateList(Operation.java:574)
> >

--
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