2

I'm trying to send a file using JSCH over SFTP protocol.

Here is the FileService file

public class FileService {

    public void send(){
        String str = "this is a test";
        InputStream is = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
        try {
            var channel = setupJsch();
            channel.put(is, "test.txt");
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
        }
    }
    
    private ChannelSftp setupJsch() throws JSchException {
        JSch jsch = new JSch();
        Session jschSession = jsch.getSession("foo", "localhost", 2222);
        jschSession.setPassword("pass");
        jschSession.setConfig("StrictHostKeyChecking", "no");
        jschSession.connect();
        return (ChannelSftp) jschSession.openChannel("sftp");
    }
}

But the JSch is throwing a NullPointException with this message: java.lang.NullPointerException: Cannot invoke "com.jcraft.jsch.Channel$MyPipedInputStream.updateReadSide()" because "this.io_in" is null

I already tried with OutputStream and the result is the same.

Could you help me?

[Update 1]

After trying the @Ogod suggestion

    public void send(){
        String str = "this is a test";
        InputStream is = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
        try {
            var channel = setupJsch();
            channel.start();
            channel.put(is, "test.txt");
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
        }
    }

It has thrown the following message java.io.IOException: channel is broken

  • @user207421 The original error was the `NullPointerException`. In a comment (which is deleted now - why?) I suggested to try `channel.start()` before `channel.put(...)`. Because this suggestion was not completly right, the next error was the `IOException`. – Ogod Jun 05 '21 at 11:21
  • `channel.start()` was just a step in the right direction but this method shouldn't be called externally. The right method is `channel.connect()` which is written down in my answer. Anyway the block [Update 1] in the question should be removed because it is confusing without the comments which aren't available anymore. – Ogod Jun 05 '21 at 12:00

1 Answers1

8

You are just missing the call to channel.connect() right before executing channel.put(...). This will setup the channel so that the internal variable io_in is assigned to an InputStream (this fixes the NullPointerException).

Additionally you should properly close the channel if you don't need it anymore by calling channel.disconnect() or channel.exit(). This will ensure that all resources are released.

public class FileService {

    public void send(){
        String str = "this is a test";
        InputStream is = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
        try {
            var channel = setupJsch();
            channel.connect();   // this should do the trick
            channel.put(is, "test.txt");
            channel.exit();      // don't forget this
        } catch (JSchException | SftpException e) {
            e.printStackTrace();
        }
    }
    
    private ChannelSftp setupJsch() throws JSchException {
        JSch jsch = new JSch();
        Session jschSession = jsch.getSession("foo", "localhost", 2222);
        jschSession.setPassword("pass");
        jschSession.setConfig("StrictHostKeyChecking", "no");
        jschSession.connect();
        return (ChannelSftp) jschSession.openChannel("sftp");
    }
}
Ogod
  • 878
  • 1
  • 7
  • 15
  • 1
    This would be a better answer if you explained, in words and not just code, what the problem was, and how you addressed it. – VGR Jun 04 '21 at 18:52
  • @VGR thanks for the hint, I have added an explanation to my answer that hopefully clarifies a bit what was the source of the error. – Ogod Jun 05 '21 at 10:20