You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@cxf.apache.org by "Thomas Carsuzan (JIRA)" <ji...@apache.org> on 2012/10/19 16:20:11 UTC

[jira] [Created] (CXF-4586) Management of spring context and bean definition

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