Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-4586

Management of spring context and bean definition

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Open
    • Major
    • Resolution: Unresolved
    • 2.5, 2.6, 2.7
    • None
    • Bus, Core
    • None
    • Unknown

    Description

      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.

      Attachments

        Activity

          People

            Unassigned Unassigned
            tetradeus Thomas Carsuzan
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated: