Details
Description
The cxf application will throw ConcurrentModificationException when creating mutiple WebService client in mutiple thread in the same time.
Here is to create WebService client source code:
JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
factory.setServiceClass(SystemPortType.class);
factory.setAddress(wsdlPort);
SystemPortType isspt = (SystemPortType) factory.create();
((BindingProvider) isspt).getRequestContext().put(BindingProvider.SESSION_MAINTAIN_PROPERTY, true);
Here is the ConcurrentModificationException stack track, notice only to create mutiple WebService client in the same time will throw this exception:
Caused by: java.util.ConcurrentModificationException
at java.util.AbstractList$Itr.checkForComodification(Unknown Source)
at java.util.AbstractList$Itr.remove(Unknown Source)
at org.apache.cxf.bus.extension.ExtensionManagerImpl.activateAllByType(ExtensionManagerImpl.java:115)
at org.apache.cxf.bus.extension.DeferredMap.undefer(DeferredMap.java:36)
at org.apache.cxf.transport.DestinationFactoryManagerImpl.getDestinationFactoryForUri(DestinationFactoryManagerImpl.java:140)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpointInfo(AbstractWSDLBasedEndpointFactory.java:239)
at org.apache.cxf.frontend.AbstractWSDLBasedEndpointFactory.createEndpoint(AbstractWSDLBasedEndpointFactory.java:145)
at org.apache.cxf.frontend.ClientFactoryBean.create(ClientFactoryBean.java:51)
at org.apache.cxf.frontend.ClientProxyFactoryBean.create(ClientProxyFactoryBean.java:102)
at org.apache.cxf.jaxws.JaxWsProxyFactoryBean.create(JaxWsProxyFactoryBean.java:121)
I did some research and found this couses that different thread try to operate the map in class ExtensionManagerImpl, the map was defined
by ConcurrentHashMap<String, ArrayList<Extension>> deferred, although ConcurrentHashMap is Multithread-Safe but ArrayList is not, Here is a piece of cxf code will trigger the exception,
public <T> void activateAllByType(Class<T> type) {
for (Map.Entry<String, Collection<Extension>> e : deferred.entrySet()) {
Iterator<Extension> it = e.getValue().iterator();
while (it.hasNext()) {
Extension ex = it.next();
if (type.isAssignableFrom(ex.getClassObject(loader)))
}
}
}
why you didn't declare this method as synchronized? I found some else methods both declare as synchronized such as activateAll(), activateViaNS(). so I tried to did some changes which declare activateAllByType() as synchronized everything work fine.
This maybe your bug I hope you fix it asap, This is very important for our current project. really thank you