Search code examples
spring-integration

Replace file when exists not working in Spring Integration Smb


I'm trying to write files to smb folder, it works fine for the first write but when the same file is written again it throws error

Caused by: org.springframework.core.NestedIOException: Failed to rename [/remote-target-dir/smbTest.test.writing] to [/remote-target-dir/smbTest.test].; nested exception is jcifs.smb.SmbException: Cannot create a file when that file already exists.

Im' using the FileTransferringMessageHandler which has FileExistsMode.REPLACE as default file exists mode but still it fails to replace.

I debugged into the SmbSession class, when flow reaches to this code in rename(String _pathFrom, String _pathTo) method

  if (this.smbShare.isReplaceFile() && smbFileTo.exists()) {
            smbFileTo.delete();
  }

I see that the smbShare's isReplaceFile() is false, which is why I assume it is unable to delete the previous file with the same name

Here is the full code:

Connection:

 @Bean
public SmbSessionFactory smbSessionFactory() {
    SmbSessionFactory smbSession = new SmbSessionFactory();
    smbSession.setHost("localhost");
    smbSession.setPort(445);
    smbSession.setDomain("DESKTOP-07O79IT");
    smbSession.setUsername("Dell");
    smbSession.setPassword("changeIt");
    smbSession.setShareAndDir("Users\\DELL\\Desktop\\Shared");
    smbSession.setSmbMinVersion(DialectVersion.SMB210);
    smbSession.setSmbMaxVersion(DialectVersion.SMB311);
    return smbSession;
}

Outbound to send files to smb:

@ServiceActivator(inputChannel = "storeToSmb")
@Bean
public MessageHandler smbMessageHandler(SmbSessionFactory smbSessionFactory) {
    FileTransferringMessageHandler<SmbFile> handler =
            new FileTransferringMessageHandler<>(smbSessionFactory);
    handler.setRemoteDirectoryExpression(
            new LiteralExpression("/remote-target-dir"));
    handler.setFileNameGenerator(m -> "smbTest.test");
    handler.setAutoCreateDirectory(true);
    return handler;
}

Gateway:

@Override
public void run(ApplicationArguments args) throws Exception {
    File file  = new File("smbFile.txt");
    try(FileWriter writer = new FileWriter(file)){
        writer.write("This is sample smb write");
        messageGateway.storeToSmb(file);
    }catch (IOException e){
        System.out.println("Error: "+e);
    }
}

Can you please help with this issue?


Solution

  • The SmbSessionFactory must come with the setReplaceFile(true). The FileTransferringMessageHandler does nothing about its dependency and can't mutate it although it has its own logic about that FileExistsMode.REPLACE.