[ 
https://issues.apache.org/jira/browse/CXF-8590?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Freeman Yue Fang resolved CXF-8590.
-----------------------------------
    Fix Version/s: 3.5.0
                   3.4.5
       Resolution: Fixed

> First invocation of method causes NPE failure in neethi.PolicyBuilder
> ---------------------------------------------------------------------
>
>                 Key: CXF-8590
>                 URL: https://issues.apache.org/jira/browse/CXF-8590
>             Project: CXF
>          Issue Type: Bug
>          Components: Core, WS-* Components
>    Affects Versions: 3.4.4
>            Reporter: Kim Johan Andersson
>            Assignee: Freeman Yue Fang
>            Priority: Major
>             Fix For: 3.4.5, 3.5.0
>
>
> I have a multithreaded application where each thread does the following:
> new SomeService
>  .getPort()
>  .invokeSomeEndpointMethod()
>  
> The first invocation of the endpoint method cases the following error:
> {noformat}
> java.lang.reflect.InvocationTargetException
>       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>       at 
> sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>       at 
> sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>       at java.lang.reflect.Method.invoke(Method.java:498)
>       at 
> org.apache.neethi.builders.converters.ConverterRegistry.findQName(ConverterRegistry.java:121)
>       at 
> org.apache.neethi.PolicyBuilder.processOperationElement(PolicyBuilder.java:204)
>       at 
> org.apache.neethi.PolicyBuilder.getPolicyOperator(PolicyBuilder.java:174)
>       at org.apache.neethi.PolicyBuilder.getPolicy(PolicyBuilder.java:124)
>       at 
> org.apache.cxf.ws.policy.attachment.wsdl11.Wsdl11AttachmentPolicyProvider.getElementPolicy(Wsdl11AttachmentPolicyProvider.java:192)
>       at 
> org.apache.cxf.ws.policy.attachment.wsdl11.Wsdl11AttachmentPolicyProvider.getElementPolicy(Wsdl11AttachmentPolicyProvider.java:168)
>       at 
> org.apache.cxf.ws.policy.attachment.wsdl11.Wsdl11AttachmentPolicyProvider.getElementPolicy(Wsdl11AttachmentPolicyProvider.java:161)
>       at 
> org.apache.cxf.ws.policy.attachment.wsdl11.Wsdl11AttachmentPolicyProvider.getEffectivePolicy(Wsdl11AttachmentPolicyProvider.java:75)
>       at 
> org.apache.cxf.ws.policy.PolicyEngineImpl.getAggregatedServicePolicy(PolicyEngineImpl.java:461)
>       at 
> org.apache.cxf.ws.policy.EndpointPolicyImpl.initializePolicy(EndpointPolicyImpl.java:151)
>       at 
> org.apache.cxf.ws.policy.EndpointPolicyImpl.initialize(EndpointPolicyImpl.java:140)
>       at 
> org.apache.cxf.ws.policy.PolicyEngineImpl.createEndpointPolicyInfo(PolicyEngineImpl.java:614)
>       at 
> org.apache.cxf.ws.policy.PolicyEngineImpl.getEndpointPolicy(PolicyEngineImpl.java:326)
>       at 
> org.apache.cxf.ws.policy.PolicyEngineImpl.getClientEndpointPolicy(PolicyEngineImpl.java:313)
>       at 
> org.apache.cxf.ws.policy.PolicyDataEngineImpl.getClientEndpointPolicy(PolicyDataEngineImpl.java:61)
>       at 
> org.apache.cxf.transport.http.HTTPConduit.updateClientPolicy(HTTPConduit.java:326)
>       at 
> org.apache.cxf.transport.http.HTTPConduit.updateClientPolicy(HTTPConduit.java:346)
>       at 
> org.apache.cxf.transport.http.HTTPConduit.getClient(HTTPConduit.java:892)
>       at 
> org.apache.cxf.transport.http.HTTPConduit.configureConduitFromEndpointInfo(HTTPConduit.java:368)
>       at 
> org.apache.cxf.transport.http.HTTPConduit.finalizeConfig(HTTPConduit.java:448)
>       at 
> org.apache.cxf.transport.http.HTTPTransportFactory.getConduit(HTTPTransportFactory.java:249)
>       at 
> org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:226)
>       at 
> org.apache.cxf.binding.soap.SoapTransportFactory.getConduit(SoapTransportFactory.java:233)
>       at 
> org.apache.cxf.endpoint.AbstractConduitSelector.createConduit(AbstractConduitSelector.java:144)
>       at 
> org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:108)
>       at 
> org.apache.cxf.endpoint.UpfrontConduitSelector.prepare(UpfrontConduitSelector.java:63)
>       at 
> org.apache.cxf.endpoint.ClientImpl.prepareConduitSelector(ClientImpl.java:887)
>       at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:525)
>       at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:441)
>       at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:356)
>       at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:314)
>       at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
>       at 
> org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:140)
> ...
>       at 
> org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:573)
> Caused by: java.lang.NullPointerException
>       at 
> com.sun.org.apache.xerces.internal.dom.DeferredElementNSImpl.synchronizeData(DeferredElementNSImpl.java:108)
>       at 
> com.sun.org.apache.xerces.internal.dom.ElementNSImpl.getLocalName(ElementNSImpl.java:338)
>       at 
> org.apache.neethi.builders.converters.AbstractDOMConverter.getQName(AbstractDOMConverter.java:43)
>       ... 45 more
> {noformat}
>  
> From there on, everything works fine. The service in question uses policies, 
> and apparently policies are lazily initialized. 
> The actual failure is triggered by a race condition causing ElementNSImpl 
> from xerces to be being shared across threads as a consequence.
> This happens in 
> org.apache.cxf.ws.policy.attachment.wsdl11.Wsdl11AttachmentPolicyProvider.getElementPolicy,
>  when the PolicyRegistry is consulted:
> {noformat}
>                         Policy policy = registry.lookup(id);
>                         if (policy == null) {
>                             try {
>                                 policy = builder.getPolicy(e.getElement());
> {noformat}
>  
> All threads will start building the missing policy, as there is nothing in 
> the registry and no synchronization on a cache miss. Some thread wins the 
> race and gets a usable result from e.getElement() and stores the result in 
> the registry, the others hit the NPE-error.
> I do not really understand all the internal workings, but I can cure this 
> problem by changing the code snippet to:
> {noformat}
>                         synchronized (e.getElement()) {
>                            Policy policy = registry.lookup(id);
>                            if (policy == null) {
>                                try {
>                                    policy = builder.getPolicy(e.getElement());
>                                    
>                            ...
>                         }
> {noformat}
> That solves the race to initialize the entry in the registry, but not the 
> real problem.
> This leaves me with 3 questions:
> Is there a way to eagerly populate the PolicyRegistry as an user of CXF?
> Shouldn't Wsdl11AttachmentPolicyProvider be thread safe, if policies are to 
> be lazily initialized?
> How do we prevent the WSDLManager in the Service from sharing non-tread safe 
> items (ElementNSImpl) across threads? 
> Apparently org.apache.cxf.jaxws.ServiceImpl.initialize always selects the 
> same bus, which cases the WSDLManager to be shared between threads. Normally 
> that would be a good thing, since we can share the WSDL-cache.
> I tried to build a test-case, so far I have no luck in building the required 
> configuration. Also, which submodule is to blame here? A lot of components 
> are involved.
> Please ask for more details if required.
> Thanks,
>  Kim Johan Andersson
>  
>  



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to