Spring Integration中RemoteFileTemplate<SmbFile>使用及日志警告排查
问题描述
在Spring的@Component中注入SmbSessionFactory以创建RemoteFileTemplate<SmbFile>,其process方法由Rest接口触发并被多次调用。代码能成功写入SMB文件,但日志中出现jcifs相关警告(如连接未正确释放、路径解析异常等),具体代码和日志如下:
代码示例
public void process(Message myMessage, String filename) { StopWatch stopWatch = StopWatch.createStarted(); byte[] bytes = marshallMessage(myMessage); String destination = smbConfig.getDir() + filename + ".xml"; if (log.isDebugEnabled()) { log.debug("Result: {}", new String(bytes)); } Optional<IOException> optionalEx = remoteFileTemplate.execute( session -> { try (InputStream inputStream = new ByteArrayInputStream(bytes)) { session.write(inputStream, destination); } catch (IOException e1) { return Optional.of(e1); } return Optional.empty(); }); log.info("processed Message in {}", stopWatch.formatTime()); optionalEx.ifPresent( ioe -> { throw new UncheckedIOException(ioe); }); }
日志警告信息
DEBUG my.package.MyClass Result: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>.... INFO org.springframework.integration.smb.session.SmbSessionFactory SMB share init: XXX WARN jcifs.smb.SmbResourceLocatorImpl Path consumed out of range 15 WARN jcifs.smb.SmbTreeImpl Disconnected tree while still in use SmbTree[share=XXX,service=null,tid=1,inDfs=true,inDomainDfs=true,connectionState=3,usage=2] INFO org.springframework.integration.smb.session.SmbSession Successfully wrote remote file [path\to\myfile.xml]. WARN jcifs.smb.SmbSessionImpl Logging off session while still in use SmbSession[credentials=XXX,targetHost=XXX,targetDomain=XXX,uid=0,connectionState=3,usage=1]:[SmbTree[share=XXX,service=null,tid=1,inDfs=false,inDomainDfs=false,connectionState=0,usage=1], SmbTree[share=XXX,service=null,tid=5,inDfs=false,inDomainDfs=false,connectionState=2,usage=0]] jcifs.smb.SmbTransportImpl Disconnecting transport while still in use Transport746[XXX/999.999.999.999:445,state=5,signingEnforced=false,usage=1]: [SmbSession[credentials=XXX,targetHost=XXX,targetDomain=XXX,uid=0,connectionState=2,usage=1], SmbSession[credentials=XXX,targetHost=XXX,targetDomain=null,uid=0,connectionState=2,usage=0]] INFO my.package.MyClass processed Message in 00:00:00.268
原因与解决办法
1. 路径格式不规范引发解析错误
日志中的Path consumed out of range 15警告,说明SMB路径解析时出现异常,大概率是路径使用了Windows本地的反斜杠\,或者路径拼接时缺少分隔符导致格式混乱。
修复方式:
- 统一使用正斜杠
/作为SMB路径的分隔符,避免反斜杠引发的解析问题; - 路径拼接时确保目录结尾带有分隔符,比如改用字符串格式化处理路径:
String dir = smbConfig.getDir().replaceAll("\\\\", "/"); if (!dir.endsWith("/")) { dir += "/"; } String destination = dir + filename + ".xml";
2. DFS共享场景下的资源泄漏问题
日志中提到inDfs=true,说明目标是DFS共享目录。旧版本的jcifs-ng在处理DFS会话时,存在资源计数不准确的问题,导致会话、连接树未被正确释放。
修复方式:
- 升级jcifs-ng依赖到最新稳定版本(Spring Integration SMB通常依赖jcifs-ng,确保版本匹配);
- 在
SmbSessionFactory配置中增加DFS相关参数,显式启用DFS支持:@Bean public SmbSessionFactory smbSessionFactory() { SmbSessionFactory factory = new SmbSessionFactory(); // 其他配置:用户名、密码、共享地址等 factory.setDfsEnabled(true); return factory; }
3. 会话资源回收机制验证
虽然RemoteFileTemplate.execute()理论上会自动管理会话的创建与关闭,但如果回调逻辑中存在未捕获的隐性异常,可能导致会话资源未被正确回收。
验证与优化:
- 检查回调中的
session.write()是否可能抛出未被捕获的非IOException类型异常; - 确保回调逻辑没有持有会话的引用,避免影响Spring自动回收会话的流程。
内容的提问来源于stack exchange,提问作者Friso
相关产品推荐
相关产品推荐

