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

Tomasz Nurkiewicz commented on CXF-3558:
----------------------------------------

Thank you very much for your comment. I am perfectly aware client is 
thread-safe once created and this is the way I use it typically. But I started 
to play a bit with clustering/failover features in Apache CXF which state in 
their JavaDocs ({{LoadDistributorFeature}} and {{FailoverTargetSelector}}): 
_Note that this feature changes the conduit on the fly and thus makes the 
Client not thread safe._

So my solution was to pool the clients and create as many clients as necessary 
using just one factory (username/password etc. won't change once configured). 
And this is where the problem manifests - if two threads simultaneously try to 
create two CXF clients (since they shouldn't share the same one due to the 
load-balancing/failover restrictions mentioned above). I wrote some small 
[article|http://nurkiewicz.blogspot.com/2011/05/enabling-load-balancing-and-failover-in.html]
 about it.

> JaxWsProxyFactoryBean.create is not thread-safe
> -----------------------------------------------
>
>                 Key: CXF-3558
>                 URL: https://issues.apache.org/jira/browse/CXF-3558
>             Project: CXF
>          Issue Type: Bug
>          Components: JAX-WS Runtime
>    Affects Versions: 2.4
>            Reporter: Tomasz Nurkiewicz
>            Assignee: Freeman Fang
>         Attachments: CXF-3558.txt
>
>
> While running {{JaxWsProxyFactoryBean.create}} concurrently I encountered the 
> following exception:
> {code}Caused by: java.util.ConcurrentModificationException
>       at 
> java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:761)
>       at java.util.LinkedList$ListItr.next(LinkedList.java:696)
>       at 
> org.apache.cxf.service.factory.AbstractServiceFactoryBean.sendEvent(AbstractServiceFactoryBean.java:71)
>       at 
> org.apache.cxf.service.factory.ReflectionServiceFactoryBean.create(ReflectionServiceFactoryBean.java:238)
>       at 
> org.apache.cxf.jaxws.support.JaxWsServiceFactoryBean.create(JaxWsServiceFactoryBean.java:202)
>       at 
> org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:101)
>       at 
> org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:90)
>       at 
> org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:152)
>       at 
> org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:142)
> {code}
> Although not documented (?), 
> {{org.apache.cxf.service.factory.ReflectionServiceFactoryBean#create}} called 
> somewhere during endpoint creation is {{synchronized}} which suggests whole 
> {{create}} is thread-safe, but apparently it's not.
> I managed to discover source of this problem. I captured two threads: one 
> ({{pool-1-thread-4}}) entered synchronized 
> {{ReflectionServiceFactoryBean#create}}, the second one ({{pool-1-thread-2}}) 
> didn't made there yet but instead it calls 
> {{AbstractServiceFactoryBean.setBus}} outside of the {{synchronized}} block. 
> This causes the 
> {{org.apache.cxf.service.factory.AbstractServiceFactoryBean#listeners}} to be 
> updated, making the former thread being susceptible to 
> {{ConcurrentModificationException}}. Stack dumps attached.
> Please either fix concurrency issue (making {{listeners}} instance of 
> {{java.util.concurrent.CopyOnWriteArrayList}} might not be enough though) or 
> document that {{JaxWsProxyFactoryBean.create}} is not thread-safe.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to