spring-integration

How to get rid of the warning: `java.lang.RuntimeException: No beanFactory`


I am working on a project. My goal is to design a Spring IntegrationFlow using Version 6.3.2. that reads from a Sftp Server and splits and transforms the received XML files.

I have two simple SftpInbound IntegrationFlow Beans reading from a Sftp Server and feeding into a merging Flwo to process further. I get this warning.

java.lang.RuntimeException: No beanFactory
    at org.springframework.integration.expression.ExpressionUtils.createStandardEvaluationContext(ExpressionUtils.java:90) ~[spring-integration-core-6.3.2.jar:6.3.2]
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizer.afterPropertiesSet(AbstractInboundFileSynchronizer.java:290) ~[spring-integration-file-6.3.2.jar:6.3.2]
    at org.springframework.integration.file.remote.synchronizer.AbstractInboundFileSynchronizingMessageSource.onInit(AbstractInboundFileSynchronizingMessageSource.java:200) ~[spring-integration-file-6.3.2.jar:6.3.2]
    at org.springframework.integration.util.AbstractExpressionEvaluator.afterPropertiesSet(AbstractExpressionEvaluator.java:93) ~[spring-integration-core-6.3.2.jar:6.3.2]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1853) ~[spring-beans-6.1.11.jar:6.1.11]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1802) ~[spring-beans-6.1.11.jar:6.1.11]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.11.jar:6.1.11]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.11.jar:6.1.11]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.11.jar:6.1.11]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.11.jar:6.1.11]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.11.jar:6.1.11]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.11.jar:6.1.11]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.11.jar:6.1.11]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:971) ~[spring-context-6.1.11.jar:6.1.11]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:625) ~[spring-context-6.1.11.jar:6.1.11]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.2.jar:3.3.2]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.2.jar:3.3.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.2.jar:3.3.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.2.jar:3.3.2]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.2.jar:3.3.2]
    at de.securess.utils.ihrrobotintegration.MainApplication.main(MainApplication.java:10) ~[classes/:na]

The code is working, but I would like to resolve the problem leading to the warning. This is my @Configuration class:

@Configuration
public class SftpIntegrationConfig {

    @Bean
    public SessionFactory<SftpClient.DirEntry> sessionFactory() {
        return getDirEntrySessionFactory();
    }


    SessionFactory<SftpClient.DirEntry> getDirEntrySessionFactory() {
        DefaultSftpSessionFactory sessionFactory = new DefaultSftpSessionFactory();
        sessionFactory.setHost("localhost");
        sessionFactory.setPort(22);
        sessionFactory.setUser("test");
        sessionFactory.setPassword("test");
        sessionFactory.setAllowUnknownKeys(true);
        sessionFactory.isSharedSession();
        return new CachingSessionFactory<>(sessionFactory);
    }

    private SftpInboundFileSynchronizer createFileSynchronizer(String remoteDirectory) {
        SftpInboundFileSynchronizer fileSynchronizer = new SftpInboundFileSynchronizer(sessionFactory());
        fileSynchronizer.setDeleteRemoteFiles(true);
        fileSynchronizer.setRemoteDirectory(remoteDirectory);
        fileSynchronizer.setFilter(new SftpSimplePatternFileListFilter("*.xml"));
        return fileSynchronizer;
    }

    private MessageSource<File> sftpMessageSource(SftpInboundFileSynchronizer fileSynchronizer) {
        SftpInboundFileSynchronizingMessageSource source = new SftpInboundFileSynchronizingMessageSource(fileSynchronizer);
        source.setLocalDirectory(new File("C:\\Users\\jb\\src\\ihr-robot-integration\\target_folder"));
        source.setAutoCreateLocalDirectory(true);
        source.setLocalFilter(new AcceptOnceFileListFilter<File>());
        source.setMaxFetchSize(1);
        return source;
    }

    @Bean
    public MessageSource<File> sftpMessageSource987597720() {
        return sftpMessageSource(createFileSynchronizer("data/987597720"));
    }

    @Bean
    public MessageSource<File> sftpMessageSource999999999() {
        return sftpMessageSource(createFileSynchronizer("data/999999999"));
    }

    @Bean
    public IntegrationFlow sftpFlow987597720() {

        return IntegrationFlow.from(sftpMessageSource987597720(),
                        c -> c.poller(Pollers.fixedDelay(10000)))
                .channel("sftpChannel")
                .get();
    }

    @Bean
    public IntegrationFlow sftpFlow999999999() {
        return IntegrationFlow.from(sftpMessageSource999999999(),
                        c -> c.poller(Pollers.fixedDelay(10000)))
                .channel("sftpChannel")
                .get();
    }

    @Bean
    public IntegrationFlow mergedSftpFlow(){
        return IntegrationFlow.from("sftpChannel")
                .channel("processChannel")
                .handle(message -> System.out.println(String.format("Processing new incoming file named: %s", message.getHeaders().get("file_name"))))
                .get();
    }

}

Can anybody help me with this warning? It seems I can't find a clue in the documentation.


Solution

  • The SftpInboundFileSynchronizer has to be as a bean. However I wonder why the factory from the Sftp and its returned builder don't work for you:

    /**
     * An {@link SftpInboundChannelAdapterSpec} factory for an inbound channel adapter spec.
     * @param sessionFactory the session factory.
     * @return the spec.
     */
    public static SftpInboundChannelAdapterSpec inboundAdapter(SessionFactory<SftpClient.DirEntry> sessionFactory) {
        return inboundAdapter(sessionFactory, null);
    }
    

    With solution for your like this:

        private SftpInboundChannelAdapterSpec sftpMessageSource(String remoteDirectory) {
            return Sftp.inboundAdapter(sessionFactory())
                    .localDirectory(new File("C:\\Users\\jb\\src\\ihr-robot-integration\\target_folder"))
                    .autoCreateLocalDirectory(true)
                    .localFilter(new AcceptOnceFileListFilter<>())
                    .maxFetchSize(1)
                    .deleteRemoteFiles(true)
                    .filter(new SftpSimplePatternFileListFilter("*.xml"))
                    .remoteDirectory(remoteDirectory);
        }
    
        private SftpInboundChannelAdapterSpec sftpMessageSource987597720() {
            return sftpMessageSource("data/987597720");
        }
        
        private SftpInboundChannelAdapterSpec sftpMessageSource999999999() {
            return sftpMessageSource("data/999999999");
        }
    

    However your scenario might really fit into a RotatingServerAdvice functionality: https://docs.spring.io/spring-integration/reference/sftp/rotating-server-advice.html