You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Freeman Yue Fang (Jira)" <ji...@apache.org> on 2021/09/02 18:30:00 UTC

[jira] [Resolved] (CXF-8590) First invocation of method causes NPE failure in neethi.PolicyBuilder

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