Commons VFS - Cannot list the contents of a directory
-
12-12-2019 - |
Question
I have a problem with Commons VFS. I want to connect to a directory using SFTP and list it. Here is the code:
FileSystemOptions opts = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
FileSystemManager fsManager = VFS.getManager();
FileObject sourceDir = fsManager.resolveFile(sourceUrl, opts);
FileObject targetDir = fsManager.resolveFile(config.get("to"));
for (FileObject sourceFile : sourceDir.getChildren()) { // here is the problem
FileObject targetFile = fsManager.resolveFile(targetDir + "/" + nodeName + "_"
+ sourceFile.getName().getBaseName());
logger.debug("Copying files. Source: " + sourceFile.getName().getPath() + " Target: "
+ targetFile.getName().getPath());
}
It seems that the fsManager
resolves it correctly but getChildren()
fails. I found out that the sourceDir
is an IMAGINARY
type; the following code says it
logger.debug(sourceDir.getType());
I checked the file and it's an ordinary folder - not a link or something like that.
Error
org.apache.commons.vfs2.FileNotFolderException: Could not list the contents of "sftp://path/to/dir" because it is not a folder.
at org.apache.commons.vfs2.provider.AbstractFileObject.getChildren(AbstractFileObject.java:693)
at pkg.services.impl.QuartzJobEventLog.downloadEventLogs(QuartzJobEventLog.java:64)
at pkg.services.impl.QuartzJobEventLog.executeJob(QuartzJobEventLog.java:37)
at pkg.services.impl.AbstractQuartzJob.execute(AbstractQuartzJob.java:25)
at $QuartzJob_1360635dbcd.execute($QuartzJob_1360635dbcd.java)
at org.quartz.core.JobRunShell.run(JobRunShell.java:203)
at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:520)
Solution
According to the documentation getting "directory contents" is not supported for the SFTP filesystem.
OTHER TIPS
Depending on which version of VFS solution will be different. For VFS 2.0 you have to include additional config option below.
SftpFileSystemConfigBuilder.getInstance( ).setUserDirIsRoot(opts, false);
Faced the same problem when we upgraded the VFS version 1.0 to 2.1 and found that documentation gives to right direction as we need to set below flag to avoid using relative path from user's home directory.
By default, the path is relative to the user's home directory. This can be changed with:
FtpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(options, false);
https://commons.apache.org/proper/commons-vfs/filesystems.html#SFTP
I was working with FTP and not SFTP protocol but encounterd the same problem as Tomas described. What helped was enabling passive mode
FtpFileSystemConfigBuilder.getInstance().setPassiveMode(opts, true);