подключиться к БД с помощью S SH java - PullRequest
0 голосов
/ 10 июля 2020

Я пытался подключиться к Oracle DB в java, но столкнулся с ошибкой и много раз искал, что не нашел, что мне помогло.

когда я пытался подключиться с помощью SQL разработчика, его успех.

поэтому я попытался написать код java для доступа к БД, его успешное подключение к S SH, но я столкнулся с ошибкой при достижении conn = DriverManager.getConnection:

"java. sql .SQLException: Io exception: Oracle Error ORA-12650 "

Это моя функция

public static Connection sshTunel() {
        String sshHost = "sshHost";
        String sshuser = "sshUser";
        String SshKeyFilepath =
            "pathOfKey";
        Session session;
        int localPort = 22;
        String remoteHost = "HostIp";
        int remotePort = 1521;
        String usr = "DB user";
        String pwd = "DB pass";
        try {
            java.util.Properties config = new java.util.Properties();
            JSch jsch = new JSch();
            session = jsch.getSession(sshuser, sshHost, 22);
            jsch.addIdentity(SshKeyFilepath, "ssh Pass");
            config.put("StrictHostKeyChecking", "no");
            config.put("Compression", "yes");
            config.put("ConnectionAttempts", "2");
            session.setConfig(config);
            session.connect();

            System.out.println("SSH Connected ...");

            int assinged_port =
                session.setPortForwardingL(localPort, remoteHost, remotePort);

            System.out.println("localhost:" + assinged_port + " -> " +
                               remoteHost + ":" + remotePort);
            System.out.println("Port Forwarded ...");
            try {
                Class.forName("oracle.jdbc.pool.OracleDataSource");

                conn =
DriverManager.getConnection("jdbc:oracle:thin:@remoteHost:1521/SID",
                            "DB User", "DB Pass");
            } catch (SQLException ex) {
                ex.printStackTrace();
                System.out.println("Error in connection");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

enter image description here

введите описание изображения здесь

1 Ответ

2 голосов
/ 10 июля 2020

S SH подключается к порту 22. Локальный порт для туннеля должен быть другим незарезервированным портом, например, 61521.

Затем вы используете локальный адрес и порт в SQL*Net URL для подключения.

Таким образом, показаны только соответствующие части:

    int localPort = 61521;
    String remoteHost = "HostIp";
    int remotePort = 1521;
    ...
    try {
        java.util.Properties config = new java.util.Properties();
        JSch jsch = new JSch();
        session = jsch.getSession(sshuser, sshHost, 22);
        ...
        session.setConfig(config);

        session.connect();

        System.out.println("SSH Connected ...");

        int assinged_port =
            session.setPortForwardingL(localPort, remoteHost, remotePort);

        System.out.println("localhost:" + assinged_port + " -> " +
                           remoteHost + ":" + remotePort);

        try {
            Class.forName("oracle.jdbc.pool.OracleDataSource");

            conn = DriverManager.getConnection(
                       "jdbc:oracle:thin:@localhost:61521/service_name",
                       "DB User", "DB Pass");
        } catch (SQLException ex) {
        ...

На снимке экрана SQL Developer я ожидал, что первое значение Host будет вашим удаленным хостом, т.е. независимо от того, какой `" sshHost "на самом деле присутствует в вашем коде; который S SH связывается с портом 22. Вторые значения Host и Port показывают, как прослушиватель базы данных достигает сеанса S SH, а не вами. ('localhost' - это удаленный сервер; что он видит как локальный хост и достигает адреса обратной связи 127.0.0.1). При выборе переключателя это соединение S SH выделяет свой собственный локальный порт и подключается к нему, и вам действительно не нужно знать, какое у него значение.

В вашем коде этот вызов :

jsch.getSession(sshuser, sshHost, 22);

это эквивалент первого узла и порта в диалоговом окне разработчика SQL. Опять же, sshHost - это значение в этом первом поле Host.

Тогда этот вызов:

session.setPortForwardingL(localPort, remoteHost, remotePort);

эквивалентен второму разделу Host и Port в вашем SQL скриншоте разработчика . Здесь remoteHost - это значение хоста, возможно, localhost; и remotePort - значение порта, равное 1521.

Отличие от настройки SQL Developer - это значение localPort. В SQL Developer, который назначается автоматически (потому что вы выбрали «автоматически назначать локальный порт»). В вашем коде вы указываете себя, и это значение должно быть незарезервированным портом.

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

jsch.getSession(sshuser, 'your_remote_host', 22);
session.connect();
session.setPortForwardingL(61521, 'localhost', 1521);
DriverManager.getConnection(
                   "jdbc:oracle:thin:@localhost:61521/service_name"

Может немного сбить с толку то, что есть две ссылки на localhost и что они, кажется, означают несколько разные вещи. Это потому, что это специальный адрес обратной петли, который остается внутри компьютера (отсюда «локальный»). Вы можете думать о первом (в setPortForwaringL) как о внутренней ссылке удаленного сервера на самого себя; а второй (в getConnection()) в качестве внутренней ссылки вашего P C на сам .

Еще больше сбивает с толку то, что ваш снимок экрана показывает localhost для обоих хостов ценности. Если это то, что у вас действительно есть, тогда это не имеет особого смысла, и вам вообще не нужно S SH. Итак, я предполагаю, что вы изменили реальное значение, чтобы скрыть его для публикации, и просто выбрали сбивающее с толку фальшивое значение вместо использования sshHost или hostIP или аналогичных.

...