I am trying to connect to Azure DB with the jTDS Driver version 1.2.7 in Android Studio. I got this error: "SQL Error: Reason: Login failed due to client TLS version being less than minimal TLS version allowed by the server." Already tried changing the TLS version on Azure and still got the same error. I also tried adding ssl=request to the end of the connection string, but I end up getting another error:
AndroidRuntime: FATAL EXCEPTION: main
Process: com.capstone.rideshareapp, PID: 6440
java.lang.NoClassDefFoundError: Failed resolution of: Lcom/sun/net/ssl/SSLContext;
at net.sourceforge.jtds.ssl.SocketFactoriesSUN$TdsTlsSocketFactory.factory(SocketFactoriesSUN.java:174)
at net.sourceforge.jtds.ssl.SocketFactoriesSUN$TdsTlsSocketFactory.getFactory(SocketFactoriesSUN.java:157)
at net.sourceforge.jtds.ssl.SocketFactoriesSUN$TdsTlsSocketFactory.createSocket(SocketFactoriesSUN.java:86)
at net.sourceforge.jtds.jdbc.SharedSocket.enableEncryption(SharedSocket.java:332)
at net.sourceforge.jtds.jdbc.TdsCore.negotiateSSL(TdsCore.java:554)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.<init>(ConnectionJDBC2.java:350)
at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:188)
at java.sql.DriverManager.getConnection(DriverManager.java:580)
at java.sql.DriverManager.getConnection(DriverManager.java:236)
at com.capstone.rideshareapp.MainActivity.connectionClass(MainActivity.java:68)
at com.capstone.rideshareapp.MainActivity.onCreate(MainActivity.java:42)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.sun.net.ssl.SSLContext" on path: DexPathList[[zip file "/data/app/com.capstone.rideshareapp-c0eguH-FO1sEfSOTqUd8qw==/base.apk"],nativeLibraryDirectories=[/data/app/com.capstone.rideshareapp-c0eguH-FO1sEfSOTqUd8qw==/lib/x86, /system/lib, /system/product/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:196)
at java.lang.ClassLoader.loadClass(ClassLoader.java:379)
at java.lang.ClassLoader.loadClass(ClassLoader.java:312)
at net.sourceforge.jtds.ssl.SocketFactoriesSUN$TdsTlsSocketFactory.factory(SocketFactoriesSUN.java:174)
at net.sourceforge.jtds.ssl.SocketFactoriesSUN$TdsTlsSocketFactory.getFactory(SocketFactoriesSUN.java:157)
at net.sourceforge.jtds.ssl.SocketFactoriesSUN$TdsTlsSocketFactory.createSocket(SocketFactoriesSUN.java:86)
at net.sourceforge.jtds.jdbc.SharedSocket.enableEncryption(SharedSocket.java:332)
at net.sourceforge.jtds.jdbc.TdsCore.negotiateSSL(TdsCore.java:554)
at net.sourceforge.jtds.jdbc.ConnectionJDBC2.<init>(ConnectionJDBC2.java:350)
at net.sourceforge.jtds.jdbc.Driver.connect(Driver.java:188)
at java.sql.DriverManager.getConnection(DriverManager.java:580)
at java.sql.DriverManager.getConnection(DriverManager.java:236)
at com.capstone.rideshareapp.MainActivity.connectionClass(MainActivity.java:68)
at com.capstone.rideshareapp.MainActivity.onCreate(MainActivity.java:42)
at android.app.Activity.performCreate(Activity.java:7802)
at android.app.Activity.performCreate(Activity.java:7791)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1299)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3245)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3409)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:83)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2016)
at android.os.Handler.dispatchMessage(Handler.java:107)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7356)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:930)
I haven't been able to figure out what has been causing this error either. On top of trying the jTDS Driver, I've also tried the Microsoft JDBC Driver and still run into errors that I seem to not be able to figure out either. The error with the JDBC Driver is this: "SQL Error: The driver could not establish a secure connection to SQL Server by using Secure Sockets Layer (SSL) encryption. Error: "Socket is closed". ClientConnectionId"
build.gradle (:app) :
plugins {
id 'com.android.application'
}
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
defaultConfig {
applicationId "com.capstone.rideshareapp"
minSdkVersion 24
targetSdkVersion 30
versionCode 1
versionName "1.0"
// multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
// def multidex_version = "2.0.1"
// implementation "androidx.multidex:multidex:$multidex_version"
implementation 'androidx.appcompat:appcompat:1.3.0'
implementation 'com.google.android.material:material:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation files('libs/jtds-1.2.7.jar')
testImplementation 'junit:junit:4.+'
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
}
MainActivity.java :
package com.capstone.rideshareapp;
import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
import android.os.StrictMode;
import android.util.Log;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class MainActivity extends AppCompatActivity {
// db connection string
static private final String connectionURL = "jdbc:jtds:sqlserver://myschooldata.database.windows" +
".net:1433;DatabaseName=MySchoolData;sslProtocol=TLSv1;user=*****@myschooldata;password=******;" +
"encrypt=true;trustServerCertificate=false;hostNameInCertificate=*.database.windows" +
".net;loginTimeout=30;";
static protected Connection connection = null;
Button signUpBtn;
Button loginBtn;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
connectionClass();
signUpBtn = findViewById(R.id.signUpBtn);
signUpBtn.setOnClickListener(v -> switchToRegister());
loginBtn = findViewById(R.id.loginBtn);
loginBtn.setOnClickListener(v -> switchToLogin());
}
private void switchToRegister() {
Intent switchToCreateAccount = new Intent(this, CreateAccount.class);
startActivity(switchToCreateAccount);
}
private void switchToLogin() {
Intent switchToLogin = new Intent(this, Login.class);
startActivity(switchToLogin);
}
// can be called in another activity using MainActivity.connectionClass()
@SuppressLint("NewApi")
static protected void connectionClass() {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance();
connection = DriverManager.getConnection(connectionURL);
Log.i("Connected", "It works");
}
catch (SQLException se) {
Log.e("SQL Error", se.getMessage());
}
catch (ClassNotFoundException e) {
Log.e("Loading Error", e.getMessage());
}
catch (Exception e) {
Log.e("Error", e.getMessage());
}
}
}
As a clarification, when using the different drivers, I changed the connection strings, the dependency for the used driver, and the Class.forName().
Does anyone know why, after trying different possible solutions, I keep getting these errors for either the jTDS Driver or the JDBC Driver?