spring-integration: Question: Potential bug with sftp session reuse?
Is there something we are supposed to do to close SFTP sessions? If we leave a service running for ore than a couple of days (anecdotal I know), this is the error we see:
Caused by: java.io.IOException: inputstream is closed com.jcraft.jsch.ChannelSftp.fill(ChannelSftp.java:2911) ~[jsch-0.1.54.jar!/:na] com.jcraft.jsch.ChannelSftp.header(ChannelSftp.java:2935) ~[jsch-0.1.54.jar!/:na] com.jcraft.jsch.ChannelSftp._put(ChannelSftp.java:583) ~[jsch-0.1.54.jar!/:na]
org.springframework.integration.sftp.session.SftpSession.write(SftpSession.java:155) ~[spring-integration-sftp-5.0.9.RELEASE.jar!/:5.0.9.RELEASE]
If we restart the service, it’ll immediately start “working” again.
My guess as perhaps some sort of connection pool is remaining open, or maybe there is some setting I am omitting to ensure the connections/sessions are handled properly.
Code:
@Configuration
@RequiredArgsConstructor
@EnableConfigurationProperties(SftpProperties.class)
@IntegrationComponentScan
@EnableIntegration
public class SftpConfiguration {
private final SftpProperties properties;
@Bean
@ConditionalOnMissingBean(name = "sftpSessionFactory")
public SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory() {
final DefaultSftpSessionFactory sessionFactory = new DefaultSftpSessionFactory();
sessionFactory.setHost(properties.getHost());
sessionFactory.setPort(properties.getPort());
sessionFactory.setUser(properties.getUser());
sessionFactory.setPassword(properties.getPassword());
sessionFactory.setAllowUnknownKeys(true);
return new CachingSessionFactory<>(sessionFactory);
}
@Bean
@ServiceActivator(inputChannel = "test")
public MessageHandler handler(@Autowired final SessionFactory<ChannelSftp.LsEntry> sftpSessionFactory) {
final SftpMessageHandler handler = new SftpMessageHandler(sftpSessionFactory);
handler.setRemoteDirectoryExpression(new LiteralExpression(properties.getDirectory()));
handler.setFileNameGenerator(message -> namingService.getName());
handler.setUseTemporaryFileName(false);
handler.setCharset(UTF_8.name());
return handler;
}
}
Could this be down to the use of a CachingSessionFactory? If this is the case, is there some process (like with JDBC connection pools) that would be used to keep connections alive or evict “dead” ones periodically?
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 16 (9 by maintainers)
Commits related to this issue
- GH-2605: (S)FTP test cached sessions Resolves https://github.com/spring-projects/spring-integration/issues/2605 — committed to garyrussell/spring-integration by garyrussell 6 years ago
- GH-2605: (S)FTP test cached sessions Resolves https://github.com/spring-projects/spring-integration/issues/2605 — committed to garyrussell/spring-integration by garyrussell 6 years ago
- GH-2605: (S)FTP test cached sessions Resolves https://github.com/spring-projects/spring-integration/issues/2605 * Suppress unused field warning. * Fix typos. * Use lstat() - don't follow sym... — committed to spring-projects/spring-integration by garyrussell 6 years ago
When we get a cached session for the pool, we check it’s open state…
For SFTP, this maps to…
So, perhaps JSch is not correctly reporting a closed session.
I suppose we could consider enhancing the
isStale()method to perform some simple operation instead.Oh! Sorry. I see what you mean. I have missed this line
return new CachingSessionFactory<>(sessionFactory);. Well, try to make a separate bean:The
DefaultSftpSessionFactoryhas to be managed by the application context as well.