javaspring-bootspring-integrationspring-messaging

Dispatcher has no subscribers for outgoing sftp channel


I'm using spring-integration-sftp and my goal is to push local file to SFTP (just that for now, without confirmation or anything else). My configuration is as follows:

@EnableIntegration
@IntegrationComponentScan
@Configuration
@Lazy
public class SftpConfiguration {

    @Bean(name = "toSftpChannel")
    public MessageChannel sftpMessageChannel() {
        return new DirectChannel();
    }

    @Bean
    public DefaultSftpSessionFactory sftpSessionFactory(
            @Qualifier("sftpDestination") SftpPropertiesService sftpPropertiesService 
    ) {
        DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory();
        factory.setHost(sftpPropertiesService.getServiceHost());
        factory.setPort(22);
        factory.setUser(sftpPropertiesService.getUsername());
        factory.setPassword(sftpPropertiesService.getPassword());
        factory.setAllowUnknownKeys(true);
        return factory;
    }

    @Bean
    public SftpRemoteFileTemplate sftpRemoteFileTemplate(DefaultSftpSessionFactory dssf,
            @Value("${sftp.output.directory}") String outputDirectory) {
        SftpRemoteFileTemplate template = new SftpRemoteFileTemplate(dssf);
        template.setRemoteDirectoryExpression(new LiteralExpression(outputDirectory));
        return template;
    }

    @Bean
    @ServiceActivator(inputChannel = "toSftpChannel")
    public MessageHandler handler(SftpRemoteFileTemplate sftpRemoteFileTemplate) {
        SftpOutboundGateway gateway =
            new SftpOutboundGateway(sftpRemoteFileTemplate, Command.PUT.getCommand(), "payload");
        gateway.setFileExistsMode(FileExistsMode.FAIL);
        return gateway;
    }

    @MessagingGateway
    public interface OutputSftpGateway {
        @Gateway(requestChannel = "toSftpChannel")
        void sendToSftp(File file);
    }
}

and sending is just

private final OutputSftpGateway outputSftpGateway;
...
outputSftpGateway.sendToSftp(file);

When I'm running my code I at first get

A bean definition with name 'toSftpChannel' exists, but failed to be created; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'toSftpChannel': Requested bean is currently in creation: Is there an unresolvable circular reference?

which is kind of expected with lazy init (though still will have to fix it), but at the second and subsequent runs I'm getting stuck with

Exception occurred during request processing. org.springframework.messaging.MessageDeliveryException. Dispatcher has no subscribers for channel 'application.toSftpChannel'.; nested exception is org.springframework.integration.MessageDispatchingException: Dispatcher has no subscribers

I'll honestly admit that I'm new with Spring messaging magic, so the cause is probably very stupid but can someone give me a hint why this is happening and how can I fix it?


Solution

  • The @Lazy may have some effect on those beans initialization. Consider to divide your configuration logic to extract only those beans which cannot live with @Lazy. And don't apply it for those Spring Integration components.