javaspringspring-integrationsmbjcifs

UnknownHostException: null using Spring Integration SMB


I try to write some files on a SMB share using Spring Integration SMB. I have the following configuration:

@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);
    }
}

which is based on Spring documentation: https://docs.spring.io/spring-integration/reference/smb.html#smb-outbound.

In my application.yml, I set the expected values like this:

samba:
  host: "192.168.1.45"
  port: 445
  domain: "WORKGROUP"
  username: "username"
  password: "password"
  share: "downloads"

Then, I try to write a service which sends files to the SMB server:

@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);
    }
}

However, whenever I try to use it, I get an UnknownHostException: null and I can't figure out why it happens. Here is the stack I get:

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

Solution

  • I answer to myself: the issue was caused by a special character in the password.