从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
相关产品推荐
相关产品推荐

