使用Spring Integration SMB时遭遇UnknownHostException: null问题求助
Spring Integration SMB 写入文件抛出 UnknownHostException: null 问题排查
问题场景
尝试使用Spring Integration SMB向SMB共享目录写入文件,完成配置与服务编写后,调用服务时始终抛出UnknownHostException: null错误,无法正常连接SMB服务器。
相关代码与配置
配置类
@Configuration public class SambaConfiguration { @Value("${samba.host}") private String host; @Value("${samba.port}") private int port; @Value("${samba.domain}") private String domain; @Value("${samba.username}") private String username; @Value("${samba.password}") private String password; @Value("${samba.share}") private String share; @Bean public SmbSessionFactory smbSessionFactory() { SmbSessionFactory smbSession = new SmbSessionFactory(); smbSession.setHost(host); smbSession.setPort(port); smbSession.setDomain(domain); smbSession.setUsername(username); smbSession.setPassword(password); smbSession.setShareAndDir(share); smbSession.setSmbMinVersion(DialectVersion.SMB202); smbSession.setSmbMaxVersion(DialectVersion.SMB311); return smbSession; } @Bean public MessageHandler smbMessageHandler(SmbSessionFactory smbSessionFactory) { SmbMessageHandler handler = new SmbMessageHandler(smbSessionFactory); handler.setRemoteDirectoryExpressionString("'/remote'"); handler.setAutoCreateDirectory(true); return handler; } @Bean public IntegrationFlow smbOutboundFlow(SmbSessionFactory smbSessionFactory) { return IntegrationFlow.from("toSmbChannel").handle( Smb.outboundAdapter(smbSessionFactory, FileExistsMode.REPLACE) .useTemporaryFileName(false) .fileNameExpression("headers['" + FileHeaders.FILENAME + "']") .remoteDirectory("smbTarget") ).get(); } @MessagingGateway public interface SmbMessagingGateway { @Gateway(requestChannel = "toSmbChannel") void sendToSmb(File file); } }
application.yml 配置
samba: host: "192.168.1.45" port: 445 domain: "WORKGROUP" username: "username" password: "password" share: "downloads"
服务实现类
@Service public class SambaServiceImpl implements SambaService { private final SmbMessagingGateway smbMessagingGateway; @Autowired public SambaServiceImpl(SmbMessagingGateway smbMessagingGateway) { this.smbMessagingGateway = smbMessagingGateway; } @Override public void sendFile(String destinationFilePath, byte[] fileBytes) throws IOException { File file = new File(destinationFilePath); FileUtils.writeByteArrayToFile(file, fileBytes); smbMessagingGateway.sendToSmb(file); } }
报错堆栈信息
Caused by: java.io.IOException: Unable to initialize share: smb://WORKGROUP;username:******@192.168.1.45:445/downloads at org.springframework.integration.smb.session.SmbShare.init(SmbShare.java:118) at org.springframework.integration.smb.session.SmbSessionFactory.createSession(SmbSessionFactory.java:86) at org.springframework.integration.smb.session.SmbSessionFactory.getSession(SmbSessionFactory.java:62) ... 79 common frames omitted Caused by: jcifs.smb.SmbException: Failed to connect to server at jcifs.smb.SmbTreeConnection.connectWrapException(SmbTreeConnection.java:429) at jcifs.smb.SmbFile.ensureTreeConnected(SmbFile.java:573) at jcifs.smb.SmbFile.getType(SmbFile.java:920) at jcifs.smb.SmbFile.canRead(SmbFile.java:1070) at org.springframework.integration.smb.session.SmbShare.init(SmbShare.java:107) ... 81 common frames omitted Caused by: java.net.UnknownHostException: null at jcifs.netbios.NameServiceClientImpl.getAllByName(NameServiceClientImpl.java:978) at jcifs.netbios.NameServiceClientImpl.getAllByName(NameServiceClientImpl.java:55) at jcifs.smb.SmbTransportPoolImpl.getSmbTransport(SmbTransportPoolImpl.java:173) at jcifs.smb.SmbTransportPoolImpl.getSmbTransport(SmbTransportPoolImpl.java:48) at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:565) at jcifs.smb.SmbTreeConnection.connectHost(SmbTreeConnection.java:489) at jcifs.smb.SmbTreeConnection.connect(SmbTreeConnection.java:465) at jcifs.smb.SmbTreeConnection.connectWrapException(SmbTreeConnection.java:426) ... 85 common frames omitted
排查方向与解决方法
1. 禁用NetBIOS名称解析
报错核心是jcifs库尝试NetBIOS名称解析失败,而你使用的是IP地址连接,无需NetBIOS解析。修改SmbSessionFactory配置,添加禁用NetBIOS的参数:
@Bean public SmbSessionFactory smbSessionFactory() { SmbSessionFactory smbSession = new SmbSessionFactory(); // 保留原有配置 smbSession.setHost(host); smbSession.setPort(port); smbSession.setDomain(domain); smbSession.setUsername(username); smbSession.setPassword(password); smbSession.setShareAndDir(share); smbSession.setSmbMinVersion(DialectVersion.SMB202); smbSession.setSmbMaxVersion(DialectVersion.SMB311); // 添加以下配置禁用NetBIOS Properties jcifsProps = new Properties(); jcifsProps.setProperty("jcifs.disableNetbios", "true"); jcifsProps.setProperty("jcifs.smb.client.useSMB2Only", "true"); smbSession.setJcifsProperties(jcifsProps); return smbSession; }
2. 验证SMB服务器基础连通性
- 检查应用服务器与SMB服务器的网络连通性,确保445端口未被防火墙拦截。
- 使用SMB客户端工具(如smbclient)从应用服务器测试连接:
若工具连接失败,优先排查网络或SMB服务器权限配置问题。smbclient //192.168.1.45/downloads -U username%password -W WORKGROUP
3. 确认SMB版本兼容性
检查目标SMB服务器是否支持SMB2.02及以上版本(你配置的最低版本为SMB202),若服务器仅支持SMB1,需调整smbMinVersion为DialectVersion.SMB1,或升级服务器SMB版本。
4. 校验配置参数注入正确性
在SmbSessionFactory方法中添加日志打印,确认host、share等参数是否正确从application.yml注入,避免参数为空或错误。
内容的提问来源于stack exchange,提问作者LeGaulois88
相关产品推荐
相关产品推荐

