Search code examples
javaspringsoapcxf

Instantiating a cxf service causes injection failure for other unrelated service


I am developing a Consumer Service for some Webservice. The application is already providing Webservices (as a server), but this is the first consumer.

The generation is ok, but I encounter a weird -to me!- problem as soon as I try to instantiate the javax.xml.ws.Service from the constructor of a consumer service : all provider webservices implementor bean become suddenly "undefined" (if I comment the first provider from cxf.xml, the second one is also 'undefined' as well).

Looks like I trigger some unexpected injection that may happen too soon... but I don't understand why, and how to fix it! Any idea is welcome!

The error trace :

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someService' defined in class path resource [spring-core-context.xml]: Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.my.services.impl.com.my.services.impl.SomeServiceImpl]: Constructor threw exception; nested exception is java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someProviderWebService': Cannot resolve reference to bean 'someProviderWebServiceImplementor' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'someProviderWebServiceImplementor' is defined at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:254)

...

Caused by: org.springframework.beans.BeanInstantiationException: Could not instantiate bean class [com.my.services.impl.com.my.services.impl.SomeServiceImpl: Constructor threw exception; nested exception is java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someProviderWebService': Cannot resolve reference to bean 'someProviderWebServiceImplementor' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'someProviderWebServiceImplementor' is defined at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:115)

...

Caused by: java.lang.RuntimeException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someProviderWebService': Cannot resolve reference to bean 'someProviderWebServiceImplementor' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'someProviderWebServiceImplementor' is defined at org.apache.cxf.bus.spring.SpringBusFactory.createBus(SpringBusFactory.java:97)

...

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'someProviderWebService': Cannot resolve reference to bean 'someProviderWebServiceImplementor' while setting constructor argument; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'someProviderWebServiceImplementor' is defined at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:275) ... Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'someProviderWebServiceImplementor' is defined at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:387)

...

(last)

the cxf.xml

  <jaxws:endpoint 
      id="someProviderWebService" 
      implementor="#someProviderWebServiceImplementor" 
      address="/services/SomeProviderWebService"/>
  <jaxws:endpoint 
      id="someProviderWebService2" 
      implementor="#someProviderWebServiceImplementor2" 
      address="/services/SomeProviderWebService2"/>

    <bean id="logInbound" class="org.apache.cxf.interceptor.LoggingInInterceptor" />
    <bean id="logOutbound" class="org.apache.cxf.interceptor.LoggingOutInterceptor" />

    <cxf:bus>
        <cxf:inInterceptors><ref bean="logInbound" /></cxf:inInterceptors>
        <cxf:outInterceptors><ref bean="logOutbound" /></cxf:outInterceptors>
        <cxf:inFaultInterceptors><ref bean="logInbound" /></cxf:inFaultInterceptors>
        <cxf:outFaultInterceptors><ref bean="logOutbound" /></cxf:outFaultInterceptors>
    </cxf:bus> 

The someServiceImpl:

    public SomeServiceImpl() throws MalformedURLException {
        SomeConsumerService service= new SomeConsumerService (); // this is the line causing the problem
    }

The webService SomeConsumerService :

public class SomeConsumerService extends javax.xml.ws.Service{

    public final static URL WSDL_LOCATION;
    public final static QName SERVICE = new QName("urn:test.com:anywhere/webservice/T", "SomeService");
    static {
        URL url = null;
        try {
            url = new URL("http://some.wsdl");
        } catch (MalformedURLException e) {
            System.err.println("Ooops! ");
        }
        WSDL_LOCATION = url;
    }

    public SomeConsumerService () {
        super(WSDL_LOCATION, SERVICE);
    }
}

The Context :

<bean name="someService" class="com.my.services.impl.SomeServiceImpl">
</bean>

<bean name="someProviderWebServiceImplementor"  class="com.my.services.impl.SomeProviderWebServiceImplementorImpl">
</bean>

Solution

  • A workmate managed to find out the problem : looks like the cxf servlet will create its own context based on cxf.xml (only!) when it is present. If it is not, it will look for its configuration in application Context.

    Though, it also it is only true when I create a consumer... thus, I am not sure whether it is more of an unexpected side-effect, or a true feature.

    Anyway, the solution that works here is :

    1. rename cxf.xml to another_name_for_cxf.xml
    2. import the renamed file from application-context.xml (or whatever name you gave it)

      <import resource="classpath:another_name_for_cxf.xml"/>
      

    And then, the magic will start to operate!