JSch/SSHJ — подключение к SSH-серверу по нажатию кнопки

Я пытаюсь подключиться к серверу SSH Unix по нажатию кнопки (код, написанный в методе actionPerformed()). Я использую JSch для подключения к серверу SSH. Код написан в классе SwingWorker, так как это сетевая операция.

private void testConnectionButtonActionPerformed(java.awt.event.ActionEvent evt) {                                                     

        SwingWorker<Boolean, Void> sw = new SwingWorker<Boolean, Void>(){

            @Override
            protected Boolean doInBackground() throws Exception {
                JSch jsch = new JSch();

                String host = "ServerHost";
                String username = "username";
                String password = "password";

                Session session = jsch.getSession(username, host);
                session.setPassword(password);

                session.setTimeout(20000);
                System.out.println("Connecting to server...");
                session.connect();

                return true;
            }

            @Override
            public void done(){
                try {
                    System.out.println(get().toString());
                } catch (Exception ex) {
                    System.out.err(ex);
                } 
            }
        };

        sw.execute();

    }  

Но после запуска с правильным хостом, именем пользователя и паролем я все время получаю следующую ошибку:

com.jcraft.jsch.JSchException: timeout: socket is not established
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
    at java.util.concurrent.FutureTask.get(FutureTask.java:83)
    at javax.swing.SwingWorker.get(SwingWorker.java:583)

Но всякий раз, когда я запускаю один и тот же код в отдельной программе, я имею в виду вместо этого писать метод actionPerformed(), если я пишу его в обычном методе и вызываю из метода main(). Это будет работать. когда я интегрирую тот же код с методом actionPerformed() Button Click, он выдаст мне вышеуказанное исключение.

Может ли кто-нибудь предложить, что я делаю неправильно здесь, или какие-либо изменения должны быть внесены в код.

Я попытался подключиться к SSH-серверу, используя реализацию «SSHJ», но получаю следующую ошибку:

java.net.SocketException: Connection reset
    at java.util.concurrent.FutureTask$Sync.innerGet(FutureTask.java:222)
    at java.util.concurrent.FutureTask.get(FutureTask.java:83)
    at javax.swing.SwingWorker.get(SwingWorker.java:583)

Может ли кто-нибудь помочь мне - как двигаться дальше?


person Sai    schedule 25.07.2011    source источник
comment
Это работает для меня (если я изменю имена серверов, пароль и настройки, чтобы принять открытый ключ сервера и исправить ваш system.out.err).   -  person Paŭlo Ebermann    schedule 25.07.2011
comment
Пауло, не могли бы вы сказать, какие настройки вы хотите, чтобы я установил для приема открытого ключа сервера, кусок кода будет очень полезен. Спасибо.   -  person Sai    schedule 26.07.2011
comment
JSch.setConfig("StrictHostKeyChecking", "no"). Но это не ваша проблема, ваша программа даже не доходит до этого момента (отказано в соединении или не разрешено). Проверьте настройки брандмауэра.   -  person Paŭlo Ebermann    schedule 26.07.2011
comment
Я сделал то же самое после того, как вы попросили меня поместить код для приема открытого ключа сервера, но он не подключался к серверу, настройки брандмауэра в порядке, потому что, когда я запускал его автономно, не помещая код в метод actionPerformed() - он будет работать, но когда я подключаю этот код с помощью метода actionPerformed() - он не подключается. Не удалось выяснить правильную причину этого. Любые дальнейшие предложения?   -  person Sai    schedule 26.07.2011


Ответы (1)


Я взял ваш код, завернул его в некоторый код графического интерфейса (и преобразовал его в не-универсальный, чтобы иметь возможность скомпилировать его с теми же настройками, что и остальные примеры JSch). Меня устраивает. Попробуйте это и сообщите, какое исключение вы получаете (у него немного больше журналов исключений).

import java.awt.event.*;
import javax.swing.*;
import java.awt.*;

import com.jcraft.jsch.*;



class SwingWorkerExample {

    JTextField hostField;
    JTextField userNameField;
    JTextField passwordField;
    JPanel panel;


    public SwingWorkerExample() {
        JPanel p = panel = new JPanel(new GridLayout(0,2));
        hostField = new JTextField(20);
        userNameField = new JTextField(20);
        passwordField = new JPasswordField(20);
        JButton testButton = new JButton("connect!");
        testButton.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent ev) {
                    testConnectionButtonActionPerformed(ev);
                }
            });
        p.add(new JLabel("host:"));
        p.add(hostField);
        p.add(new JLabel("user:"));
        p.add(userNameField);
        p.add(new JLabel("password:"));
        p.add(passwordField);
        p.add(testButton);
    }

    public JPanel getPanel() {
        return panel;
    }

    private void testConnectionButtonActionPerformed(ActionEvent evt) {

        SwingWorker sw = new SwingWorker(){

                protected Object doInBackground() throws Exception {
                    try {
                        JSch jsch = new JSch();

                        String host = hostField.getText();
                        String username = userNameField.getText();
                        String password = passwordField.getText();

                        Session session = jsch.getSession(username, host);
                        session.setPassword(password);
                        session.setConfig("StrictHostKeyChecking", "no");

                        session.setTimeout(20000);
                        System.out.println("Connecting to server...");
                        session.connect();

                        return session;
                    }
                    catch(Exception ex) {
                        ex.printStackTrace();
                        throw ex;
                    }
                }

                public void done(){
                    try {
                        System.out.println(get());
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            };

        sw.execute();

    }


    public static void main(String[] egal) {
        EventQueue.invokeLater(new Runnable(){public void run() {
            SwingWorkerExample ex = new SwingWorkerExample();
            JFrame f = new JFrame("bla");
            f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
            f.setContentPane(ex.getPanel());
            f.pack();
            f.setVisible(true);
        }});
    }
}
person Paŭlo Ebermann    schedule 26.07.2011
comment
Это также доступно на github в моем репозитории JSch-documentation. (на данный момент пример ветки swingworker). - person Paŭlo Ebermann; 26.07.2011
comment
Пауло, я выполнил твой код, он работает нормально. Я создаю графический интерфейс с помощью Netbeans 7, есть один класс: [org.jdesktop.application.ResourceMap], с помощью которого я получаю значения свойств из файла свойств. Я использую его для установки текста для кнопок, текстов меток. Если я не использую этот файл класса в коде, session.connect() работает. Я действительно не знаю отношения здесь, почему он не может подключиться. Если я использую хотя бы одну строку класса ResourceMap, она не будет подключаться. Есть мысли по этому поводу? - person Sai; 27.07.2011
comment
Понятия не имею, я никогда не использовал этот класс. Это может быть проблема с загрузчиком классов - может быть, какой-то класс дублируется в вашем пути к классам, что приводит к загрузке неправильного, если используется ResourceMap, из-за некоторых зависимостей? - person Paŭlo Ebermann; 27.07.2011
comment
этот класс отсутствует в моем пути к классу, я пробовал с javap org.jdesktop.application.ResourceMap. Странно наблюдать такое поведение, так что единственный способ — пока избегать этого класса? - person Sai; 27.07.2011