Search code examples
javasql-serverlinuxdockerjdbc

Connecting via Java from Ubuntu Subsystem or a Linux docker container to SQL Server which is installed on Windows


I am trying to connect to a sql server database which is installed on windows out of a Linux docker container or from an ubuntu subsystem with java code and it is not working. I need a real hardcore expert on this field. I know there are many solutions out there to this problem and I tried many of them, but nothing worked. The special case is that the SQL Server is installed on Windows and I have a linux docker container, so the connection has to be between os. I have tried jtds and jdbc. Here is the code which works when is executed on windows but not on linux subsystem or docker. I also tried "useNTLMv2=true" in the connectionstring:

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);

            // Iterate through the data in the result set and display it.
            while (rs.next()) {
                System.out.println(rs.getString("PLZ"));
            }
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
        }
}
}

And here ist the exception I am getting from the docker container using 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)

An ohter exception with the same code I get from ubuntu subsystem:

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)

Here is my code 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);

            // Iterate through the data in the result set and display it.
            while (rs.next()) {
                System.out.println(rs.getString("PLZ") );
            }
        }
        // Handle any errors that may have occurred.
        catch (SQLException e) {
            e.printStackTrace();
        }

                        }
        }

And here is the exception I am getting with ubuntu:

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)

I tried almost all solution which are published on the internet to this problem. I am expecting to see how I could connect to sql server which is installed on windows from linux.


Solution

  • The problem was solved by my database administrator, he created a login user who is capable of sql authentication. But first I had to check the SQL Server Logs to see what the problem was in detail, like in the comments suggested.