Tuesday, March 10, 2015

com.jcraft.jsch.JSchException: Packet corrupt

This exception occurs when the Session is reused repeatedly in a loop where the session is disconnected intentionally or due to time out and needs to reconnect again.

For example, the following code will throw such an exception at session.connect() in the while loop.

Public class SftpTest extends Thread {
       private String username = "";
       private String password = "";
       private boolean running = true;

      public SftpTest(String user, String pass) {
            username = user;
            password = pass;
      }

      public void run() {
             try {
                    JSch jsch = new JSch();
                     Session session = jsch.getSession(username, "<your host>");
                    session.setPassword(password);
                    session.setConfig("StrictHostKeyChecking", "no");
                   session.connect();

                   Channel channel = session.openChannel("sftp");
                   channel.connect();
                    ChannelSftp sftp = (ChannelSftp) channel;

                    while (running) {
                           if (!session.isConnected()) {
                                   session.connect();
                                   channel = session.openChannel("sftp");
                             }
                            if (!channel.isConnected()) {
                                   channel.connect();
                                  sftp = (ChannelSftp) channel;
                           }

                           Vector<LsEntry> entries = sftp.ls("*.pdf");
                           for (LsEntry entry : entries) {
                                   String fileName = entry.getFilename();
                                   sftp.get(fileName, ".");
                                   sftp.rm(fileName);
                            }
                            Thread.sleep(60 * 60 * 1000);//sleep for 1 hr                        
                      }
                       sftp.exit();
                       sftp.disconnect();
                       session.disconnect();
              } catch (InterruptedException ie) {
                     ie.printStackTrace();
              } catch (SftpException fe) {
                     fe.printStackTrace();
              } catch (JSchException e) {
                    e.printStackTrace();
              }
       }

       public static void main (String[] args) {
               SftpTest test = new SftpTest("<your username>", "<your password>");
               test.start()
       }
}

The reason that such an exception is thrown is that the first time the Session is connected to the remote site, a random number called Packet is generated for the session. When the thread is having its 1 hour sleep, the session gets automatically disconnected due to no activity for a certain period of time. When the Session is disconnected, the Packet is lost. When the Session is trying to reconnect, it could not find the Packet, thus the exception is thrown.

One way to solve this problem is to not reuse the same Session. If the thread is going to sleep for awhile, disconnect the Session before going to sleep and create a new Session after sleep. The above code can be rearranged as below to avoid this exception.

Public class SftpTest extends Thread {
       private String username = "";
       private String password = "";
       private boolean running = true;

      public SftpTest(String user, String pass) {
            username = user;
            password = pass;
      }

      public void run() {
             try {
                   while (running) {
                         JSch jsch = new JSch();
                         Session session = jsch.getSession(username, "<your host>");
                         session.setPassword(password);
                         session.setConfig("StrictHostKeyChecking", "no");
                         session.connect();

                        Channel channel = session.openChannel("sftp");
                        channel.connect();
                        ChannelSftp sftp = (ChannelSftp) channel;

                        Vector<LsEntry> entries = sftp.ls("*.pdf");
                        for (LsEntry entry : entries) {
                                   String fileName = entry.getFilename();
                                   sftp.get(fileName, ".");
                                   sftp.rm(fileName);
                         }
                       sftp.exit();
                       sftp.disconnect();
                       session.disconnect();
                      Thread.sleep(60 * 60 * 1000);//sleep for 1 hr
                   } //end of while loop
             } catch (InterruptedException ie) {
                     ie.printStackTrace();
              } catch (SftpException fe) {
                     fe.printStackTrace();
              } catch (JSchException e) {
                    e.printStackTrace();
              }
       }

       public static void main (String[] args) {
               SftpTest test = new SftpTest("<your username>", "<your password>");
               test.start()
       }
}
       
----------------------------------------------------------------------------------------------------------------
                        
If you have ever asked yourself these questions, this is the book for you. What is the meaning of life? Why do people suffer? What is in control of my life? Why is life the way it is? How can I stop suffering and be happy? How can I have a successful life? How can I have a life I like to have? How can I be the person I like to be? How can I be wiser and smarter? How can I have good and harmonious relations with others? Why do people meditate to achieve enlightenment? What is the true meaning of spiritual practice? Why all beings are one? Read the book free here.

2 comments:

  1. Hello,
    Might you help me with a problem I have?
    In my case, I do not do a loop, but I get the same error with some files: "com.jcraft.jsch.JSchException: Packet corrupt"
    In my function, I connect to download a file and close the session.

    ReplyDelete
  2. Hi Javier,

    This exception can occur in many situations. Have you tried to connect using a different way to ensure that it is OK to connect?

    ReplyDelete