Thomas Carsuzan created CXF-4586:
------------------------------------
Summary: Management of spring context and bean definition
Key: CXF-4586
URL: https://issues.apache.org/jira/browse/CXF-4586
Project: CXF
Issue Type: Bug
Components: Bus, Core
Affects Versions: 2.7.0, 2.6, 2.5
Reporter: Thomas Carsuzan
Hi,
In our application we have a root parent application context A and children
application contexts (spring) B.
if you look for a bean created in A from A context you get it.
if you look for a bean created in A from B context you get it.
if you look for a bean created in B from B context you get it.
if you look for a bean created in B from A context you cannot get it => (parent
context does not see children context beans).
We import cxf*.xml in our conf in the parent root context.
We define our "service/client service" in children application context.
We define next to it their conduit :
ie :
<jaxws:client id="xxx" serviceClass="xxx" address="xxx">
<jaxws:properties>
<entry key="schema-validation-enabled" value="false"/>
</jaxws:properties>
</jaxws:client>
<conduit name="{http://xxx.http-conduit"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns="http://cxf.apache.org/transports/http/configuration">
<authorization>
<sec:UserName>xxx</sec:UserName>
<sec:Password>xxx</sec:Password>
<sec:AuthorizationType>Basic</sec:AuthorizationType>
</authorization>
</conduit>
Problem : the conduit is not found at runtime.
It looks like the conduit is retrieved from the Bus, but in our application the
bus was created in the parent root application context so it has a pointer on
the root application context where it was created but cannot see beans created
in children contexts so it cannot find our conduit.
I though a solution would be to declare a specific bus in our child context
next to our service :
<cxf:bus name="yyy">
</cxf:bus>
<jaxws:client id="xxx" serviceClass="xxx" address="xxx" bus="yyy">
<jaxws:properties>
<entry key="schema-validation-enabled" value="false"/>
</jaxws:properties>
</jaxws:client>
<conduit name="{http://xxx.http-conduit"
xmlns:sec="http://cxf.apache.org/configuration/security"
xmlns="http://cxf.apache.org/transports/http/configuration">
<authorization>
<sec:UserName>xxx</sec:UserName>
<sec:Password>xxx</sec:Password>
<sec:AuthorizationType>Basic</sec:AuthorizationType>
</authorization>
</conduit>
Now the bus has a pointer on the child context so it can retrieve the correct
conduit.
PROBLEM:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named
'org.apache.cxf.binding.soap.SoapTransportFactory' is defined
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:527)
at
org.apache.cxf.bus.spring.SpringBeanLocator.hasConfiguredPropertyValue(SpringBeanLocator.java:216)
at
org.apache.cxf.transport.TransportFinder$2.loadBean(TransportFinder.java:180)
at
org.apache.cxf.bus.extension.ExtensionManagerImpl.loadBeansOfType(ExtensionManagerImpl.java:301)
at
org.apache.cxf.bus.spring.SpringBeanLocator.loadBeansOfType(SpringBeanLocator.java:210)
at
org.apache.cxf.transport.TransportFinder.loadActivationNamespaces(TransportFinder.java:185)
at
org.apache.cxf.transport.TransportFinder.findTransportForNamespace(TransportFinder.java:55)
at
org.apache.cxf.transport.ConduitInitiatorManagerImpl.getConduitInitiator(ConduitInitiatorManagerImpl.java:126)
at
org.apache.cxf.endpoint.AbstractConduitSelector.getSelectedConduit(AbstractConduitSelector.java:81)
at
org.apache.cxf.endpoint.UpfrontConduitSelector.prepare(UpfrontConduitSelector.java:61)
at
org.apache.cxf.endpoint.ClientImpl.prepareConduitSelector(ClientImpl.java:848)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:530)
There is a bug in org/apache/cxf/bus/spring/SpringBeanLocator.java
in the method boolean hasConfiguredPropertyValue(String beanName, String
propertyName, String searchValue)
Indeed, here the problematic lines :
if (context.containsBean(beanName) && !passThroughs.contains(beanName))
{
ConfigurableApplicationContext ctxt =
(ConfigurableApplicationContext)context;
BeanDefinition def =
ctxt.getBeanFactory().getBeanDefinition(beanName);
You check that the context has the bean named
'org.apache.cxf.binding.soap.SoapTransportFactory'.
The answer will be true because children contexts have access to the parent
context bean.
Then you get the beanDefinition from the child context.
The problem is that there is no bean definition in our child context but in the
parent context so we get the previous exception.
One solution would be to check the parent context bean definition too.
One quickFix is to import cxf*.xml in our child context but it then duplicates
the beans.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira