[
https://issues.apache.org/jira/browse/CXF-8590?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Kim Johan Andersson updated CXF-8590:
-------------------------------------
Description:
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
was:
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:
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
>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:
Policy policy = registry.lookup(id);
if (policy == null) {
try {
policy = builder.getPolicy(e.getElement());
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:
synchronized (e.getElement()) {
Policy policy = registry.lookup(id);
if (policy == null) {
try {
policy = builder.getPolicy(e.getElement());
...
}
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
> 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
> Priority: Major
>
> 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)