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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With