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

Reply via email to