ExceptionInInitializerError on DriverManager with MS SQL Server - java

I'm trying to connect to a MS SQL Server DB using JDBC and on this line:
String connectionUrl = "jdbc:" + url + ";user=dummy;password=dummy;";
conn = DriverManager.getConnection(connectionUrl);
I'm getting this massive wall-of-text of an error:
Exception in thread "main" java.lang.ExceptionInInitializerError
at javax.crypto.JceSecurityManager.<clinit>(JceSecurityManager.java:65)
at javax.crypto.Cipher.getConfiguredPermission(Cipher.java:2543)
at javax.crypto.Cipher.getMaxAllowedKeyLength(Cipher.java:2567)
at sun.security.ssl.CipherSuite$BulkCipher.isAvailable(CipherSuite.java:548)
at sun.security.ssl.CipherSuite$BulkCipher.isAvailable(CipherSuite.java:527)
at sun.security.ssl.CipherSuite.isAvailable(CipherSuite.java:194)
at sun.security.ssl.SSLContextImpl.getApplicableCipherSuiteList(SSLContextImpl.java:350)
at sun.security.ssl.SSLContextImpl.getDefaultCipherSuiteList(SSLContextImpl.java:308)
at sun.security.ssl.SSLSocketImpl.init(SSLSocketImpl.java:607)
at sun.security.ssl.SSLSocketImpl.<init>(SSLSocketImpl.java:549)
at sun.security.ssl.SSLSocketFactoryImpl.createSocket(SSLSocketFactoryImpl.java:110)
at com.microsoft.sqlserver.jdbc.TDSChannel.enableSSL(IOBuffer.java:1606)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1323)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:991)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
at java.sql.DriverManager.getConnection(DriverManager.java:664)
at java.sql.DriverManager.getConnection(DriverManager.java:270)
at BusinessManager.Session.<init>(Session.java:33)
at BusinessManager.BusinessManager.getSession(BusinessManager.java:172)
at example.Example.ConfigureEnvironment(Example.java:198)
at example.Example.main(Example.java:50)
Caused by: java.lang.SecurityException: Can not initialize cryptographic mechanism
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:89)
... 22 more
Caused by: java.lang.SecurityException: Cannot locate policy or framework files!
at javax.crypto.JceSecurity.setupJurisdictionPolicies(JceSecurity.java:254)
at javax.crypto.JceSecurity.access$000(JceSecurity.java:48)
at javax.crypto.JceSecurity$1.run(JceSecurity.java:81)
at java.security.AccessController.doPrivileged(Native Method)
at javax.crypto.JceSecurity.<clinit>(JceSecurity.java:78)
... 22 more
I've followed a couple of links, made sure both server and client are using the same JDK (1.8.0_20).
I've also downloaded the "JCE Unlimited Strength Jurisdiction Policy Files" and placed them in the JDK. I've also followed this link but I'm not sure whether I should be meddling with the JDK's "java.policy" files...

My guess based on the error is that you are attempting to connect to SQL with an SSL encrypted session but are using a self-signed certificate on the SQL Server. Per Connecting with SSL Encryption:
When the encrypt property is set to true and the
trustServerCertificate property is set to true, the Microsoft JDBC
Driver for SQL Server will not validate the SQL Server SSL
certificate. This is usually required for allowing connections in test
environments, such as where the SQL Server instance has only a self
signed certificate.
Try using:
String connectionUrl = "jdbc:" + url + ";user=dummy;password=dummy;encrypt=true;trustServerCertificate=true;";
Also, your url variable contents should start with sqlserver://.

Related

Connecting to SQL Server 13 with Java 17

I'm trying to connect to SQL Server 13 in a Springboot 2.7.5 after upgrading java to version 17
This is the key points the stacktrace when the application starts up and attempts to connect
Failed to obtain JDBC Connection; nested exception is com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: \"Certificates do not conform to algorithm constraints\". ClientConnectionId:3dd8afba-ccaf-451e-a8f1-5687b548ee3b\
java.security.cert.CertPathValidatorException: Algorithm constraints check failed on keysize limits: RSA 1024 bit key used with certificate: CN={SERVER_URL}
I've tried to add encrypt=true and trustServerCertificate=true to the connection url and still get the same issue.
Looking at the SQL version compatbiity list: https://learn.microsoft.com/en-us/sql/connect/jdbc/microsoft-jdbc-driver-for-sql-server-support-matrix?view=sql-server-ver16
I should be able to use com.microsoft.sqlserver:mssql-jdbc:11.2.0.jre17 also downgrading major versions also get the same result.
I'm able to connect the server using the same creds using intellij thats configured to use java 17 and using driver 11.2.1
I figured out the issue, since RHEL8 it has removed weak crypto algorithms. So, I had to update the Docker file to have RUN update-crypto-policies --set LEGACY, see also https://access.redhat.com/articles/3642912

Keycloak unable to connect to SQL Server running on Windows

Keycloak container is unable to establish connection to a remote SQL Server database and is stuck in a boot loop.
Output from container logs:
{"logs":"Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: \"Certificates do not conform to algorithm constraints\". ClientConnectionId:8c3fca80-a572-4014-abe0-6e55adf39c44
{"logs":"Caused by: javax.net.ssl.SSLHandshakeException: Certificates do not conform to algorithm constraints
{"logs":"Caused by: java.security.cert.CertificateException: Certificates do not conform to algorithm constraints
{"logs":"Caused by: java.security.cert.CertPathValidatorException: Algorithm constraints check failed on keysize limits. RSA 1024bit key used with certificate:
CN=SSL_Self_Signed_Fallback. Usage was tls server
{"logs":"\u001B[0m\u001B[31m12:14:07,280 FATAL [org.keycloak.services] (ServerService Thread Pool -- 56) java.lang.RuntimeException: Failed to connect to database
I’m running Keycloak version 10.0.1 in a docker container on a Linux machine and the SQL Server 2012 DB is hosted on a Windows machine. I've enabled TCP/IP protocol on the SQL Server and configured it to listen on all addresses.
Works absolutely fine when I point the container to SQL Server running on another Linux machine.

Trouble connecting to SQL server using Java

This is what I've written as part of my code:
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
String host1 = "<URL/Connection path string>";
String uname1= "<User name>";
String pwd1 = "<Password>";
Connection con1 =DriverManager.getConnection(host1,uname1,pwd1);
Statement stmt1 = con1.createStatement();
ResultSet rs = stmt1.executeQuery("<Query>");
I've used the following jar files: jtds-1.3.0, sqljdbc-4.1.5605, sqljdbc4-4.0
when I ran the code, I got the following error:
Exception in thread "main" com.microsoft.sqlserver.jdbc.SQLServerException: The connection to the host <host-name>, named instance <instance-name> failed. Error: "java.net.SocketTimeoutException: Receive timed out". Verify the server and instance names and check that no firewall is blocking UDP traffic to port 1434. For SQL Server 2005 or later, verify that the SQL Server Browser Service is running on the host.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.getInstancePort(SQLServerConnection.java:3589)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.primaryPermissionCheck(SQLServerConnection.java:1225)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.login(SQLServerConnection.java:972)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:827)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:1012)
at java.sql.DriverManager.getConnection(DriverManager.java:571)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at first_doc.main(first_doc.java:28)
as far as I know, there is no firewall that's blocking traffic.
Also, do I need to add Port number as part of the Connection URL?
Edit: I use SQL server version 2008
I cannot find Protocols for SQLEXPRESS in the Configuration Manager
These are the steps that you need to do. If you already did this please check again.
Download latest MSSQL JDBC driver from here: http://msdn.microsoft.com/en-us/sqlserver/aa937724.aspx
Referenced the 2 JAR files in my project:
sqljdbc.jar and sqljdbc4.jar
(I'm not yet sure if both of the above are required or just one..)
Make sure the SQL Server Browser windows service is running
Open SQL Server Configuration Manager and go to Protocols for SQLEXPRESS under SQL Server Network Configuration. Right-click on TCP/IP and choose Properties.
Set Enabled = YES.
While you're there, click on IP Addresses tab and find the section IP All.
Set TCP Port to 1433.
Add sqljdbc_auth.dll to your PATH Environment Variable. In my case:
D:\Java\sqljdbc_4.0\enu\auth\x64
Copy the sqljdbc_auth.dll to your JDK directory. In my case:
C:\Program Files\Java\jdk1.7.0_04\bin

Can't connect to SQL Server using jTDS

I'm trying to connect to SQL Server 2008 R2 via Java, and I'm unable to do so using jTDS 1.2.8. The odd thing is that it works fine using the Microsoft JDBC driver. Is there some server-side setting that needs to be turned on to enable jTDS to access it? Or am I just missing something in the URL?
I'm not using Windows integrated authentication to specify credentials, nor am I attempting to connect using SSL encryption (those are issues I found that can generate the exception I'm seeing.)
If I use the following with the Microsoft driver, it works as expected, I can access the database with no problems:
Connection connection = DriverManager.getConnection("jdbc:sqlserver://PHSSQL792\\PHSSQL792:1433", user, password);
(user and password are variables declared earlier, so I can be sure I use the same values when connecting with either driver.)
However, if I use the following with the jTDS driver:
Connection connection = DriverManager.getConnection("jdbc:jtds:sqlserver://PHSSQL792:1433;instance=PHSSQL792", user, password);
I get the following error:
java.sql.SQLException: I/O Error: DB server closed connection.
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2387)
at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:614)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.<init>(ConnectionJDBC2.java:356)
at net.sourceforge.jtds.jdbc.ConnectionJDBC3.<init>(ConnectionJDBC3.java:50)
at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:185)
at java.sql.DriverManager.getConnection(DriverManager.java:571)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at database.db_access.SqlServerDatabaseTestApp.main(SqlServerDatabaseTestApp.java:28)
Caused by: java.io.IOException: DB server closed connection.
at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:853)
at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:732)
at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:477)
at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:114)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2281)
at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:614)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.<init>(ConnectionJDBC2.java:356)
at net.sourceforge.jtds.jdbc.ConnectionJDBC3.<init>(ConnectionJDBC3.java:50)
at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:185)
at java.sql.DriverManager.getConnection(DriverManager.java:571)
at java.sql.DriverManager.getConnection(DriverManager.java:215)
at database.db_access.SqlServerDatabaseTestApp.main(SqlServerDatabaseTestApp.java:28)
I've tried connecting with and without the database name, and/or with/without the instance name, and got the same results. Any suggestions?
Edit:
Other jTDS connection URLs I've tried (which all gave me the same error as above):
"jdbc:jtds:sqlserver://PHSSQL792:1433"
"jdbc:jtds:sqlserver://PHSSQL792:1433/pacsdb"
"jdbc:jtds:sqlserver://PHSSQL792:1433/pacsdb;instance=PHSSQL792"
The corresponding Microsoft URLS (which all worked):
"jdbc:sqlserver://PHSSQL792:1433"
"jdbc:sqlserver://PHSSQL792:1433;databasename=pacsdb"
"jdbc:sqlserver://PHSSQL792\\PHSSQL792:1433;databasename=pacsdb"
Also, I can successfully connect to a different SQL Server 2008 R2 database (on a different server) using the jTDS driver, so it's not the jar.
In case anyone ever runs into this, I came back to this much later and finally figured out the problem. The SQL Server instance in question was configured to require SSL connections! I just added ssl=request to the URL to make it work.
I think the reason the Microsoft driver works without explicitly setting SSL encryption is that it ALWAYS initially connects with SSL to encrypt username/password for login. The encrypt property only controls whether data after login is encrypted.
Here's the format we are using, which looks very close to your:
jdbc:jtds:sqlserver://localhost:1433/Dev_DB;tds=8.0;lastupdatecount=true
It's strange, yours connection strings looks correct. Try to set user and password directly:
"jdbc:jtds:sqlserver://PHSSQL792:1433/pacsdb;instance=PHSSQL792;user=sa;password=pass"
String driver="net.sourceforge.jtds.jdbc.Driver";
Class.forName(driver).newInstance();
//First way
String connString="jdbc:jtds:sqlserver://192.168.1.123:1433/database_name;encrypt=false;user=sa;password=mypass;";
String username="sa";
String password="mypass";
Connection con=DriverManager.getConnection(connString,username,password);
//Second way
String connString="jdbc:jtds:sqlserver://127.0.0.1:1433/database_name;encrypt=false;user=sa;password=mypass;integratedSecurity=true;instance=SQLEXPRESS;";
String username="sa";
String password="mypass";
Connection con=DriverManager.getConnection(connString,username,password);

MS SQL Server and JDBC: closed connection

Im getting
I/O Error: DB server closed connection.
while connecting to MS SQL server 2008 from java code .
SQL server is in mixed mode and its in local machine.My connection string is
jTDS
jdbc:jtds:sqlserver://machineName:1433;databaseName=DB;integratedSecurity=true
stack trace is
java.sql.SQLException: I/O Error: DB server closed connection.
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2311)
at net.sourceforge.jtds.jdbc.TdsCore.login(TdsCore.java:610)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.(ConnectionJDBC2.java:345)
at net.sourceforge.jtds.jdbc.ConnectionJDBC3.(ConnectionJDBC3.java:50)
at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:184)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at com.app.hibernate.test.(test.java:22)
at com.app.hibernate.test.main(test.java:53)
Caused by: java.io.IOException: DB server closed connection.
at net.sourceforge.jtds.jdbc.SharedSocket.readPacket(SharedSocket.java:848)
at net.sourceforge.jtds.jdbc.SharedSocket.getNetPacket(SharedSocket.java:727)
at net.sourceforge.jtds.jdbc.ResponseStream.getPacket(ResponseStream.java:466)
at net.sourceforge.jtds.jdbc.ResponseStream.read(ResponseStream.java:103)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2206)
... 8 more
Exception in thread "main" java.lang.NullPointerException
at com.app.hibernate.test.db(test.java:36)
at com.app.hibernate.test.main(test.java:54)
JDBC Driver
String url ="jdbc:sqlserver://machine:1433;instance=SQLEXPRESS;databaseName=db";
stacktrace
com.microsoft.sqlserver.jdbc.SQLServerException: Login failed for user 'username'.
at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDatabaseError(SQLServerException.java:156)
at com.microsoft.sqlserver.jdbc.TDSTokenHandler.onEOF(tdsparser.java:240)
at com.microsoft.sqlserver.jdbc.TDSParser.parse(tdsparser.java:78)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.sendLogon(SQLServerConnection.java:2636)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.logon(SQLServerConnection.java:2046)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.access$000(SQLServerConnection.java:41)
at com.microsoft.sqlserver.jdbc.SQLServerConnection$LogonCommand.doExecute(SQLServerConnection.java:2034)
at com.microsoft.sqlserver.jdbc.TDSCommand.execute(IOBuffer.java:4003)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.executeCommand(SQLServerConnection.java:1550)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connectHelper(SQLServerConnection.java:1207)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.loginWithoutFailover(SQLServerConnection.java:1054)
at com.microsoft.sqlserver.jdbc.SQLServerConnection.connect(SQLServerConnection.java:758)
at com.microsoft.sqlserver.jdbc.SQLServerDriver.connect(SQLServerDriver.java:842)
at java.sql.DriverManager.getConnection(Unknown Source)
at java.sql.DriverManager.getConnection(Unknown Source)
at com.app.hibernate.test.(test.java:22)
at com.app.hibernate.test.main(test.java:53)
Exception in thread "main" java.lang.NullPointerException
at com.app.hibernate.test.db(test.java:36)
at com.app.hibernate.test.main(test.java:54)
Your Connection String and authentication have errors. if it is mix mode don't use SQL authentication
Try this
PC Name : janaka-pc SQL User Name : sa SQL Password
: 1234 Database : Janak_DB
Code for sql Conncetion in JDBC
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
Connection conn = DriverManager.getConnection("jdbc:sqlserver://janaka-PC;user=sa;password=1234;database=Janak_DB");
You have problems in your connection strings
For jTDS:
jdbc:jtds:sqlserver://machineName:1433;databaseName=DB;useNTLMv2=tru‌​e;domain=workgroup
You may read http://jtds.sourceforge.net/faq.html#windowsAuth for the required Single-Sign-On library for NTLM to work.
"integratedSecurity=true" that you supplied for jdts is valid when using the JDBC driver
jdbc:sqlserver://machine:1433;instance=SQLEXPRESS;databaseName=db;integratedSecurity=true
You have an authentication error in on the MS SQL side.
If you're not in control of how to adquire the connection (ie, you're using a Datasource or a Connection Pool), the connection URL must contain the login and password to be used, like:
jdbc:sqlserver://machine:1433;instance=SQLEXPRESS;databaseName=db;user=USERNAME;password=PASSWORD";
If the application is running on a Windows machine and you want to use the credentials of the logged user, then you can specify the domain parameter with or without useNTLMv2.
Finally, if you are on a windows machine but you want to authenticate the user against a domain, then you must supply the username, password and domain parameters. You can read all about it in the jtds FAQ, specially the URL Format section.

Categories

Resources