Search code examples
sftpapache-minassh2-sftp

UnsupportedOperationException in NativeSshFile.setAttributes when uploading files Apache Mina sshd Server


I start up a local SFTP server using Apache Mina SSHD. Here is my related code. To testing I use WinSCP as my SFTP client. I can connect to the server successfully and can view server root directory also. But the problem was that when I try to upload a file into that server root directory.

I got a

Exception caught in SFTP subsystem
java.lang.UnsupportedOperationException: null 
at org.apache.sshd.common.file.nativefs.NativeSshFile.setAttributes(NativeSshFile.java:634) ~[sshd-core-0.10.0.jar:0.10.0]
    at org.apache.sshd.server.sftp.SftpSubsystem.process(SftpSubsystem.java:427) ~[sshd-core-0.10.0.jar:0.10.0]
    at org.apache.sshd.server.sftp.SftpSubsystem.run(SftpSubsystem.java:334) ~[sshd-core-0.10.0.jar:0.10.0]
    at java.lang.Thread.run(Unknown Source) [na:1.7.0_75].

Below is my related log files.

10:30:46.758 [Thread-1] DEBUG o.a.s.c.file.nativefs.NativeSshFile - Authorized
10:30:46.767 [Thread-1] ERROR o.a.sshd.server.sftp.SftpSubsystem - Exception caught in SFTP subsystem
java.lang.UnsupportedOperationException: null
    at org.apache.sshd.common.file.nativefs.NativeSshFile.setAttributes(NativeSshFile.java:634) ~[sshd-core-0.10.0.jar:0.10.0]
    at org.apache.sshd.server.sftp.SftpSubsystem.process(SftpSubsystem.java:427) ~[sshd-core-0.10.0.jar:0.10.0]
    at org.apache.sshd.server.sftp.SftpSubsystem.run(SftpSubsystem.java:334) ~[sshd-core-0.10.0.jar:0.10.0]
    at java.lang.Thread.run(Unknown Source) [na:1.7.0_75]
10:30:46.767 [Thread-1] DEBUG o.a.s.server.channel.ChannelSession - Send SSH_MSG_CHANNEL_EOF on channel ChannelSession[id=0, recipient=256]
10:30:46.768 [Thread-1] DEBUG o.a.sshd.common.io.nio2.Nio2Session - Writing 64 bytes

Also my maven dependency,

<dependency>
    <groupId>org.apache.mina</groupId>
    <artifactId>mina-core</artifactId>
    <version>2.0.9</version>
</dependency>
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-sftp</artifactId>
    <version>0.9.0</version>
</dependency>
<dependency>
    <groupId>org.apache.sshd</groupId>
    <artifactId>sshd-core</artifactId>
    <version>0.10.0</version>
</dependency>

I would like to know that how can I overcome above problem when uploading files into my local SFTP server. Thanks.


Solution

  • When uploading files, WinSCP, depending on its configuration, sets uploaded file timestamp (on by default) and/or permissions (off by default).

    The Mina SSHD 0.10.0 does not support setting file attributes.

    public void setAttributes(Map<Attribute, Object> attributes) throws IOException {
        if (!attributes.isEmpty()) {
            throw new UnsupportedOperationException();
        }
    }
    

    The latest Mina SSHD 0.14.0 does support setting the timestamp and by default only logs that it cannot set the permissions (or other attributes).

    public void setAttributes(Map<Attribute, Object> attributes) throws IOException {
        Set<Attribute> unsupported = new HashSet<Attribute>();
        for (Attribute attribute : attributes.keySet()) {
            Object value = attributes.get(attribute);
            switch (attribute) {
            case Size: {
                long newSize = (Long) value;
                FileChannel outChan = new FileOutputStream(file, true).getChannel();
                outChan.truncate(newSize);
                outChan.close();
                continue;
            }
            case LastModifiedTime:
                setLastModified((Long) value);
                break;
            default:
                unsupported.add(attribute);
                break;
            }
        }
        handleUnsupportedAttributes(unsupported);
    }
    
    protected void handleUnsupportedAttributes(Collection<Attribute> attributes) {
        if (!attributes.isEmpty()) {
            StringBuilder sb = new StringBuilder();
            for (Attribute attr : attributes) {
                if (sb.length() > 0) {
                    sb.append(", ");
                }
                sb.append(attr.name());
            }
            switch (nativeFileSystemView.getUnsupportedAttributePolicy()) {
            case Ignore:
                break;
            case Warn:
                LOG.warn("Unsupported attributes: " + sb.toString());
                break;
            case ThrowException:
                throw new UnsupportedOperationException("Unsupported attributes: " + sb.toString());
            }
        }
    }