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

从Linux Docker/Ubuntu子系统通过Java连接Windows SQL Server失败求助

从Linux Docker/Ubuntu子系统连接Windows上的SQL Server失败排查与解决

尝试用Java代码从Linux Docker容器或Ubuntu子系统连接Windows主机上的SQL Server数据库,多次尝试网上方案均无效,现整理相关代码与异常,寻求可行解决方法。


一、JTDS驱动相关代码与异常

1. Windows环境正常运行的JTDS代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import net.sourceforge.jtds.jdbcx.*;
import net.sourceforge.jtds.jdbc.Driver;

public class helloWorld {
    public static void main(String[] args) throws ClassNotFoundException {
        // String connectionUrl = "jdbc:jtds:sqlserver://<db_ip>:1433;databaseName=someDB;useNTLMv2=true;";
        String connectionUrl = "jdbc:jtds:sqlserver://<server_ip>:1433;databaseName=someDB;username=xyz;password=123";
        Class.forName("net.sourceforge.jtds.jdbc.Driver");
        try (Connection con = DriverManager.getConnection(connectionUrl); Statement stmt = con.createStatement()) {
            String SQL = "SELECT [PLZ] FROM [City]";
            ResultSet rs = stmt.executeQuery(SQL);

            // 遍历结果集并输出数据
            while (rs.next()) {
                System.out.println(rs.getString("PLZ"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

2. Docker容器中JTDS连接异常

java.sql.SQLException: Network error IOException: Connection refused (Connection refused)
        at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:436)
        at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
        at java.sql.DriverManager.getConnection(DriverManager.java:664)
        at java.sql.DriverManager.getConnection(DriverManager.java:270)
        at de.arz.pharmafakt.datadelivery.Main.main(Main.java:93)
Caused by: java.net.ConnectException: Connection refused (Connection refused)
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:607)
        at net.sourceforge.jtds.jdbc.SharedSocket.createSocketForJDBC3(SharedSocket.java:288)
        at net.sourceforge.jtds.jdbc.SharedSocket.<init>(SharedSocket.java:251)
        at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:331)

3. Ubuntu子系统中JTDS连接异常

java.sql.SQLException: I/O Error: GSS Failed: Invalid name provided (Mechanism level: KrbException: Cannot locate default realm)
        at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:654)
        at net.sourceforge.jtds.jdbc.JtdsConnection.<init>(JtdsConnection.java:371)
        at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:251)
        at helloWorld.main(helloWorld.java:16)
Caused by: java.io.IOException: GSS Failed: Invalid name provided (Mechanism level: KrbException: Cannot locate default realm)
        at net.sourceforge.jtds.jdbc.TdsCore.sendMSLoginPkt(TdsCore.java:1976)
        at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:617)

二、官方JDBC驱动相关代码与异常

1. JDBC代码

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class helloWorld {
    public static void main(String[] args) {
        String connectionUrl = "jdbc:sqlserver://<server_ip>:1433;databaseName=someDB;user=xyz;password=123;Encrypt=false";

        try (Connection con = DriverManager.getConnection(connectionUrl); Statement stmt = con.createStatement();) {
            String SQL = "SELECT PLZ FROM city";
            ResultSet rs = stmt.executeQuery(SQL);

            // 遍历结果集并输出数据
            while (rs.next()) {
                System.out.println(rs.getString("PLZ"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

2. Ubuntu子系统中JDBC连接异常

com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'xyz'. ClientConnectionId:21e99cbc-bd73-40a0-8101-542ddffb3a0b
        at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:265)
        at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:305)
        at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:138)
        at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:42)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:6490)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:5068)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:5002)
        at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:7685)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:4048)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:3487)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:3077)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectInternal(SQLServerConnection.java:2919)
        at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:1787)
        at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1229)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:251)
        at helloWorld.main(helloWorld.java:16)

三、排查与解决步骤

1. 网络连通性验证

  • 在Docker容器/Ubuntu子系统中执行ping <Windows主机IP>,确认网络可达
  • 执行nc -zv <Windows主机IP> 1433或telnet <Windows主机IP> 1433,测试1433端口是否开放(解决Connection refused问题)
  • 检查Windows防火墙:添加入站规则,允许1433端口接收来自Linux子网的连接;若为WSL2,可尝试设置桥接网络或配置端口转发

2. SQL Server基础配置检查

  • 启用TCP/IP协议:打开SQL Server配置管理器,进入SQL Server网络配置→TCP/IP,设置为启用,重启SQL Server服务
  • 配置监听IP:在TCP/IP属性的IP地址选项卡中,设置IPAll的TCP端口为1433,所有IP的启用状态设为是
  • 启用混合身份验证:在SQL Server管理工具中,右键实例→属性→安全性,选择SQL Server和Windows身份验证模式,重启服务
  • 验证用户权限:确认xyz是SQL身份验证用户,已授予someDB数据库的访问权限,密码输入正确

3. JTDS驱动适配调整

针对Ubuntu子系统的GSS/Kerberos异常:

  • 修改连接字符串,强制使用SQL身份验证,添加domain=.(本地用户)并禁用NTLMv2:
    jdbc:jtds:sqlserver://<server_ip>:1433;databaseName=someDB;user=xyz;password=123;domain=.;useNTLMv2=false
    

4. 官方JDBC驱动适配调整

针对登录失败异常:

  • 修改连接字符串,添加authenticationScheme=SQLPassword强制使用SQL身份验证:
    jdbc:sqlserver://<server_ip>:1433;databaseName=someDB;user=xyz;password=123;Encrypt=false;authenticationScheme=SQLPassword
    
  • 确保使用的mssql-jdbc驱动版本与SQL Server版本兼容,建议使用最新稳定版驱动

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 15:44:52