Spring integration 'Dispatcher has no subscribers' when channels are used in init-method

spring-integration

Solution

The init/@PostConstruct method is called after your bean has been instantiated but before the rest of the context has been wired up (in this case before the RMI adapter has been subscribed to the channel).

You need to wait until the context is fully refreshed.

One way to do that is implement

ApplicationListener<ContextRefreshedEvent>

and put your code in

public void onApplicationEvent(ContextRefreshedEvent event)

That method will be called after the context is fully wired.

Problem

Getting 'Dispatcher has no subscribers' error while trying to post message to a channel in spring bean's init-method. Please take a look at below example: applicationContext.xml ``` <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:rmi="http://www.springframework.org/schema/integration/rmi" xmlns:int="http://www.springframework.org/schema/integration" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd http://www.springframework.org/schema/integration/rmi http://www.springframework.org/schema/integration/rmi/spring-integration-rmi.xsd"> <bean id="currencyService" class="com.demo.CurrencyService" init-method="init"/> <int:channel id="currencyChannel" /> <int:channel id="currencyReplyChannel"> <int:queue/> </int:channel> <rmi:outbound-gateway id="currencyServiceGateway" request-channel="currencyChannel" remote-channel="currencyServiceChannel" reply-channel="currencyReplyChannel" host="localhost" port="2197" /> </beans> ``` Spring managed bean: ``` import org.springframework.beans.factory.annotation.Autowired; import org.springframework.integration.Message; import org.springframework.integration.MessageChannel; import org.springframework.integration.core.MessagingTemplate; import org.springframework.integration.core.PollableChannel; import org.springframework.integration.message.GenericMessage; public class CurrencyService { @Autowired private MessageChannel currencyChannel; @Autowired private PollableChannel currencyReplyChannel; private CurrencyListBO currencyListBO; public CurrencyListBO getCurrencyList() { return currencyListBO; } public void init() { CurrencyIN request = new CurrencyIN(); request.setChannelCode("RMW"); request.setTransactionType(CurrencyIN.TransactionType.currencyLoaderService .toString()); GenericMessage<IRequestBO> message = new GenericMessage<IRequestBO>( request); MessagingTemplate template = new MessagingTemplate(); template.send(currencyChannel, message); Message<CurrencyListBO> reply = template.receive(currencyReplyChannel); currencyListBO = reply.getPayload(); } } ``` If instead of init-method, currencyListBO was initialized after during first call, everything works fine. ``` public CurrencyListBO getCurrencyList() { if(currencyListBO == null) { init(); } return currencyListBO; } ``` Please let me know what is the issue with first approach.

Original source