Question

I have a problem with a SFTP (Windows with WinSSHD). I try to write a file in a folder with Apache Commons VFS. On a local SFTP I have no problem with the upload but on a second SFTP I always get the error below.

The FTP looks like this: enter image description here

I need to upload into the folder "alis". What is strange is that it has no User/Group and 770 rights. However, with FileZilla the file upload works fine (same login used).

Doing a "manager.resolveFile()" on the Folder "alis" (i try to upload to this folder) and printing the ".getType()" i get the information "File" and not as expected "Folder".

Does anyone have an idea why VFS does recognize the folder as file or why the upload does not work?

The exception when uploading the file to the SFTP:

Exception in thread "main" java.lang.RuntimeException: org.apache.commons.vfs2.FileSystemException: Could not copy "file:///D:/Test/test.txt" to "sftp://user:***@host/.../alis/test.txt".
    at test.Test.upload(Test.java:77)
    at test.Test.main(Test.java:22)
Caused by: org.apache.commons.vfs2.FileSystemException: Could not copy "file:///D:/Test/test.txt" to "sftp://user:***@host/.../alis/test.txt".
    at org.apache.commons.vfs2.provider.AbstractFileObject.copyFrom(AbstractFileObject.java:1062)
    at test.Test.upload(Test.java:73)
    ... 1 more
Caused by: org.apache.commons.vfs2.FileSystemException: Could not create folder "sftp://user:***@host/.../alis" because it already exists and is a file.
    at org.apache.commons.vfs2.provider.AbstractFileObject.createFolder(AbstractFileObject.java:968)
    at org.apache.commons.vfs2.provider.AbstractFileObject.getOutputStream(AbstractFileObject.java:1424)
    at org.apache.commons.vfs2.provider.DefaultFileContent.getOutputStream(DefaultFileContent.java:461)
    at org.apache.commons.vfs2.provider.DefaultFileContent.getOutputStream(DefaultFileContent.java:441)
    at org.apache.commons.vfs2.FileUtil.copyContent(FileUtil.java:111)
    at org.apache.commons.vfs2.provider.AbstractFileObject.copyFrom(AbstractFileObject.java:1053)
    ... 2 more

Sourcecode: (to run the example you need "jsch-0.1.50.jar")

import java.io.File;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystemException;
import org.apache.commons.vfs2.FileSystemOptions;
import org.apache.commons.vfs2.Selectors;
import org.apache.commons.vfs2.impl.StandardFileSystemManager;
import org.apache.commons.vfs2.provider.sftp.SftpFileSystemConfigBuilder;

/**
 *
 * @author thbe
 */
public class Test {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        upload("host", "user", "password", "D:/Test/test.txt", "/../alis/test.txt");
    }

    public static FileSystemOptions createDefaultOptions()
            throws FileSystemException {
        // Create SFTP options
        FileSystemOptions opts = new FileSystemOptions();

        // SSH Key checking
        SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(
                opts, "no");

        // Root directory set to user home
        SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);

        // Timeout is count by Milliseconds
        SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
        SftpFileSystemConfigBuilder.getInstance().setPreferredAuthentications(opts, "publickey,keyboard-interactive,password");

        return opts;
    }

    public static void upload(String hostName, String username,
            String password, String localFilePath, String remoteFilePath) {

        File f = new File(localFilePath);
        if (!f.exists()) {
            throw new RuntimeException("Error. Local file not found");
        }

        StandardFileSystemManager manager = new StandardFileSystemManager();

        try {
            manager.init();

            // Create local file object
            FileObject localFile = manager.resolveFile(f.getAbsolutePath());

            System.out.println("open remote File");
            FileObject remoteFile = manager.resolveFile(
                    createConnectionString(hostName, username, password,
                    remoteFilePath), createDefaultOptions());

            System.out.println("exists:"+remoteFile.exists());
            System.out.println("type:"+remoteFile.getType());
            System.out.println("URL:"+remoteFile.getURL());

            System.out.println("copy to remote File");
            remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);

            System.out.println("File upload success");
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            manager.close();
        }
    }

    public static String createConnectionString(String hostName,
            String username, String password, String remoteFilePath) {
        // result: "sftp://user:123456@domainname.com/resume.pdf
        return "sftp://" + username + ":" + password + "@" + hostName + "/"
                + remoteFilePath;
    }
}
Was it helpful?

Solution

We used another way to connect and upload files to some SFTP:

public static void main(String[] args) {
    putFile("user", "host", "passwd", "/../test.txt", "C:/test.txt");
}
public static void putFile(String username, String host, String password, String remotefile,     String localfile){
    JSch jsch = new JSch();
    Session session = null;
    try {
          session = jsch.getSession(username, host, 22);
          session.setConfig("StrictHostKeyChecking", "no");
          session.setPassword(password);
          session.connect();

          Channel channel = session.openChannel("sftp");
          channel.connect();
          ChannelSftp sftpChannel = (ChannelSftp) channel;
          sftpChannel.put(localfile, remotefile);
          sftpChannel.exit();
          session.disconnect();
     } catch (JSchException e) {
          e.printStackTrace();  
     } catch (SftpException e) {
          e.printStackTrace();
     }
}

This approach should work with any SSH (SFTP) and not ask for any login information or other blocking stuff.

OTHER TIPS

You mentioned:

770 rights but no user and no group.

"Other" people do not have right to use the directory. The directory does not have user or group, therefore your SFTP client may have failed due to insufficient permission.

What happens if you assign it a user/group?

I faced the same issue. You are trying to creating folder in same location and file is exists in same location with same name.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top