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.
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