Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring-integration gateway cannot be autowired, no qualifying bean found

I am trying to send the output from a spring batch process to RabbitMQ. To avoid hard dependency on Rabbitmq, I used spring-integration as suggested in Is there an API in spring-xd to write to a message bus?. I had everything working fine with messages being pushed to RabbitMQ, until I decided to autowire or instantiate the beans via Spring.

<context:component-scan base-package="com.test.*"/> 
<channel id="input" />

<rabbit:connection-factory id="connectionFactory" />

<rabbit:template id="amqpTemplate" connection-factory="connectionFactory"
    exchange="testExchange" routing-key="foo.bar" />
<rabbit:admin connection-factory="connectionFactory" />
<rabbit:queue name="testQueue" id="timeseriesQueue" />
<rabbit:topic-exchange name="testExchange"
    id="testExchange">
    <rabbit:bindings>
        <rabbit:binding queue="testQueue" pattern="foo.*" />
    </rabbit:bindings>
</rabbit:topic-exchange>

<!-- Send message to rabbitmq -->
<gateway id="testGateway"
    service-interface="com.test.TestService"
    default-request-channel="input" />


<amqp:outbound-channel-adapter channel="input"
    amqp-template="amqpTemplate" exchange-name="testExchange"
    routing-key="foo.bar" />

The testService is just an interface with the method sendMessage.

The spring batch job has an itemWriter, which uses the gateway bean to write to RabbitMQ

In the write method of itemWriter, when I instantiated the bean using ApplicationContext, like below, it worked well

AbstractApplicationContext ctx =
                new ClassPathXmlApplicationContext("META-INF/spring/integration/rabbit.xml");

     TestService service = ctx.getBean("testGateway", TestService.class);
    service.sendMessage(items);
    ctx.close();

However, when I tried to autowire it, like below:

@Autowired
TestService service;

I get the following exception:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.test.TestService com.test.TransportItemWriter.testGateway; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.test.TestService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 22 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.test.TestService] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 24 more

I tried looking around, but most examples (in spring-integration samples) of Gateway invoke it via ApplicationContext. I found http://java.dzone.com/articles/spring-integration-gateways-1, and added whatever annotation I thought I was missing, but could not get it working.

Any pointers are greatly appreciated.

like image 234
Alice Avatar asked Dec 15 '22 16:12

Alice


2 Answers

I was dealing with similar issue recently. The solution was to add new annotation in config:

@IntegrationComponentScan("path.to.your.gateway")

like image 58
jogo Avatar answered Apr 26 '23 07:04

jogo


It's a old question I know, but I had a Similar Issue:

I would use a anotated class @MessagingGateway interface called MySFTPUploadGateway.java (is a gateway of course) placed in mydependency1.jar. Also I have a SpringBoot app called ApplicationMain.jar, but when i start my application this crash because ApplicationMain.jar, on runtime, not found MySFTPUploadGateway.class for autowiring as a Bean. I tried @ComponentScan("<path_to_MySFTPUploadGateway.class_on_mydependency1>"), also with @EnableIntegration but anything worked.

Reading a little about this, I Found https://github.com/spring-projects/spring-boot/issues/2037, cool, I think I have my solution with @IntegrationComponentScan ( the clue that gave me @jogo). But... This anotation only works with @EnableAutoConfiguration. This is the key.

So put your:

@EnableAutoConfiguration
@IntegrationComponentScan("<yourpathPackage>")

..and keep it running !

like image 39
javalderas Avatar answered Apr 26 '23 07:04

javalderas