You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

通过SSH隧道连接远程Oracle数据库失败问题求助

SSH隧道连接Oracle数据库的Java代码问题

我用数据库管理器通过SSH隧道连接远程Oracle数据库完全正常,但用Java代码复现时遇到了连接失败的问题。

我的Java代码

public void afterPropertiesSet() throws Exception {
    Session session = null;
    try {
        session = new JSch().getSession("********","1x.xx.xx.xx");
        session.setPassword("*********");
        session.setConfig("StrictHostKeyChecking", "no");
        session.connect();
        session.setPortForwardingL(1521,"xx.xx.yy.yy",1521);
        System.out.println("port forwarding completed");
        Class.forName("oracle.jdbc.OracleDriver");
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@//xx.xx.yy.yy:1521/db","********","********");
        System.out.println(conn.getMetaData().getUserName());
    }catch (Exception e){
        e.printStackTrace();
    }finally {
        if(session!=null) {
            session.disconnect();
        }
    }
}

遇到的报错情况

  • 原代码运行时,报错:

java.sql.SQLException: ORA-12541: Cannot connect. No listener at host xx.xx.yy.yy port 1521. (CONNECTION_ID=wIOJk+zFTYCI4FR7XNsHew==)

  • 将端口改为1520(主机不变),报错:

Caused by: oracle.net.ns.NetException: ORA-12541: Cannot connect. No listener at host localhost port 1520. (CONNECTION_ID=On8tBIXKQCu40izLoOLsRg==)

  • 将驱动主机改为localhost/本地实际IP(端口不变),报错:

Caused by: oracle.net.ns.NetException: ORA-12541: Cannot connect. No listener at host localhost port 1520. (CONNECTION_ID=o8/105qIRG+N9zBuyiaMZg==)


问题分析与修复

核心问题

  1. JDBC连接字符串错误:你已经通过SSH把本地端口映射到了远程数据库,但代码里还是直接访问远程主机地址,等于没走SSH隧道。
  2. 可能存在本地端口冲突:如果本地已经有Oracle监听占用了1521端口,端口转发会静默失败,导致连接不上。

修正后的代码

public void afterPropertiesSet() throws Exception {
    Session session = null;
    try {
        // 建立SSH跳板连接
        session = new JSch().getSession("你的SSH用户名","跳板机IP");
        session.setPassword("你的SSH密码");
        session.setConfig("StrictHostKeyChecking", "no");
        session.connect();
        
        // 用未被占用的本地端口(比如1520)映射到远程数据库地址和端口
        int localForwardPort = 1520;
        String remoteDbHost = "xx.xx.yy.yy";
        int remoteDbPort = 1521;
        session.setPortForwardingL(localForwardPort, remoteDbHost, remoteDbPort);
        System.out.println("端口转发完成,本地端口:" + localForwardPort);
        
        // JDBC连接本地转发的端口,而不是远程主机
        Class.forName("oracle.jdbc.OracleDriver");
        String jdbcUrl = "jdbc:oracle:thin:@//localhost:" + localForwardPort + "/db";
        Connection conn = DriverManager.getConnection(jdbcUrl, "数据库用户名", "数据库密码");
        System.out.println(conn.getMetaData().getUserName());
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        if(session != null) {
            session.disconnect();
        }
    }
}

额外检查项

  • 确认SSH跳板机可以正常ping通并访问远程数据库的1521端口
  • 用netstat -ano(Windows)或lsof -i :1520(Linux/Mac)检查本地1520端口是否被占用
  • 确保项目中依赖的JSch版本与Java环境兼容

内容的提问来源于stack exchange,提问作者Akash Jain

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 09:12:43