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)