aws-sdk-android
aws-sdk-android copied to clipboard
Unable to connect over IOT for minSDK version 19
Describe the bug My app is connected to AWS IoT using aws-android-sdk-core and aws-android-sdk-iot. I am using org.eclipse.paho:org.eclipse.paho.client.mqttv3 for the client side. However, when using minSdkVersion lower than 26(in my case it is 19), I get the error message "Could not find class 'javax.net.ssl.SNIHostName', referenced from method org.conscrypt.Platform."
To Reproduce A code sample or steps:
- set Android minsdkversion to 19 Your code
- Here is the app gradle file plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id ("kotlin-kapt") id("com.apollographql.apollo3") version "4.0.0-alpha.1" }
android { namespace 'com.eprintitsaas.avision.app' compileSdk 33
defaultConfig {
applicationId "com.eprintitsaas.avision.app"
minSdk 19
targetSdk 29
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
configurations.all {
resolutionStrategy {
force 'androidx.preference:preference:1.1.1'
force 'com.android.support:support-v4:25.1.1'
exclude group: "com.android.support", module: "support-core-utils"
exclude group: "com.android.support", module: "support-core-ui"
exclude group: 'com.google.code.gson', module: 'gson'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
apollo {
service("service") {
packageName.set("com.eprintitsaas.avision.app")
}
}
}
dependencies { implementation(files("libs/commons.jar")) implementation files('libs/WorkpathLib.aar') implementation files('libs/WorkpathLib-javadoc.jar')
implementation project(path: ':aws-android-sdk-core')
implementation project(path: ':aws-android-sdk-iot')
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
//firebase
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
implementation("com.google.firebase:firebase-crashlytics-ktx")
implementation("com.google.firebase:firebase-analytics-ktx")
/*RETROFIT 2.9.0*/
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2")
implementation("com.squareup.retrofit2:converter-scalars:2.6.4")
implementation("com.jakewharton:butterknife:10.2.3")
kapt ("com.jakewharton:butterknife-compiler:10.2.3")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
implementation("com.apollographql.apollo3:apollo-runtime:4.0.0-alpha.1")
implementation("com.apollographql.apollo:apollo-coroutines-support:2.5.14")
implementation("com.github.devsideal:VectorChildFinder:1.0.0")
implementation("androidx.multidex:multidex:2.0.1")
implementation ("androidx.appcompat:appcompat:1.6.1")
implementation ("com.google.android.material:material:1.9.0")
implementation ("androidx.constraintlayout:constraintlayout:2.1.4")
implementation ("com.android.support:support-core-utils:28.0.0")
implementation ("com.dropbox.core:dropbox-core-sdk:3.1.5")
implementation ("com.google.code.gson:gson:2.10.1")
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
implementation ("com.intuit.sdp:sdp-android:1.1.0")
implementation 'org.bouncycastle:bcpkix-jdk15on:1.67'
implementation "org.minidns:minidns-hla:0.3.2"
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
implementation 'androidx.preference:preference:1.1.1'
implementation 'com.github.bumptech.glide:glide:4.15.1'
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
}
Which AWS service(s) are affected?
- aws-android-sdk-auth-core
- aws-android-sdk-auth-iot
Expected behaviour It should be able to connect over iot
Screenshots
Environment Information (please complete the following information):
- AWS Android SDK Version: [2.73.0]
- Device: [Nexus 5 API 19]
- Android Version: [Android kitkat 4.4]
- Specific to simulators: [No]
Additional context I am encountering an error only after switching to minsdkversion 19 and installing the app on KitKat 4.4 Android OS. I have added AWS SDKs as modules and am also using the latest Eclipse Paho library.
Hello @haransanjay, thanks for reaching out. Can you briefly explain why you're using implementation project(path: ':aws-android-sdk-core')
instead of implementation 'com.amazonaws:aws-android-sdk-core:2.73.0'
etc.? We'll look into the rest of the issue as well.
Hello @tjleing, thank you for your response. The implementation was updated to the latest version, which works fine with Android SDK 26. However, there is an issue with Android 19 and this was a legacy implementation I have received.
I tried replicating the issue with minSDK set to 19 and I am able to connect, publish and subscribe messages. Could you share your code snippet ? Also which device are you testing this on?
Hello @ankpshah, Thank you for your response. Below is the MQTTManager class that I am using to establish a connection. Device names: Nexus 5 API 19, Pixel 6 API 19
class MQTTManager {
interface OnSubscribeDone {
fun onSubscribed()
fun onReconnect(globalEndPoint: String)
}
companion object {
lateinit var context: Context
lateinit var mqttManager: AWSIotMqttManager
private var keyStorePath = "./"
lateinit var topic: String
lateinit var onSubscribeDone: OnSubscribeDone
fun setContext(con: Context, onSubscribeDone: OnSubscribeDone) {
context = con
this.onSubscribeDone = onSubscribeDone
}
@Throws(Exception::class)
fun mqttConnect(
context: Context,
globalEndPoint: String,
certificate: String,
privateKey: String,
endPoint: String,
thingName: String,
custId: String,
) {
val uniqId = UUID.randomUUID().toString()
keyStorePath = context.getFilesDir().toString()+ "/"
val keystoreFileName = "name.bks"
val keystoreFilePassword = "pass"
AWSIotKeystoreHelper.createKeystore(keyStorePath,
keystoreFileName,
keystoreFilePassword)
topic = "cmd/+/" + custId + "/+/" + thingName + "/+"
mqttManager = AWSIotMqttManager(
thingName,
endPoint)
val assetManager = context.assets
var input: InputStream = privateKey.byteInputStream()
var size: Int = input.available()
val buffer = ByteArray(size)
input.read(buffer)
input.close()
val privateKeyPem = String(buffer)
input = certificate.byteInputStream()
size = input.available()
val buffer2 = ByteArray(size)
input.read(buffer2)
input.close()
val clientCertificate = String(buffer2)
val uniqueId = UUID.randomUUID().toString()
// if (!AWSIotKeystoreHelper.isKeystorePresent(keyStorePath, keystoreFileName)) { AWSIotKeystoreHelper.saveCertificateAndPrivateKey(uniqueId, clientCertificate, privateKeyPem, keyStorePath, keystoreFileName, keystoreFilePassword) // } // retrieve the keystore val keystore: KeyStore = AWSIotKeystoreHelper.getIotKeystore( uniqueId, keyStorePath, keystoreFileName, keystoreFilePassword )
// wait for connection
Thread.sleep(3000)
mqttManager.connectUsingALPN(keystore
) { status, throwable ->
if (status == AWSIotMqttClientStatusCallback.AWSIotMqttClientStatus.Connecting) {
Utils.showErrorLog("MQTT", "status: Connecting")
}
if (status == AWSIotMqttClientStatusCallback.AWSIotMqttClientStatus.Connected) {
Utils.showErrorLog("MQTT", "status: Connected")
//Subscribe
subscribe()
}
if (status == AWSIotMqttClientStatusCallback.AWSIotMqttClientStatus.ConnectionLost) {
Utils.showErrorLog("MQTT", "status: ConnectionLost")
}
if (status == AWSIotMqttClientStatusCallback.AWSIotMqttClientStatus.Reconnecting) {
Utils.showErrorLog("MQTT", "status: Reconnecting")
reconnectMQTT(globalEndPoint)
}
}
}
private fun reconnectMQTT(globalEndPoint: String) {
Utils.showErrorLog("MQTT", "Reconnect")
onSubscribeDone.onReconnect(globalEndPoint)
}
private fun subscribe() {
mqttManager.subscribeToTopic(topic,
AWSIotMqttQos.QOS0,
object : AWSIotMqttSubscriptionStatusCallback {
override fun onSuccess() {
Utils.showErrorLog("MQTT", "MQTT SUBSCRIBED")
onSubscribeDone.onSubscribed()
}
override fun onFailure(exception: Throwable) {
Utils.showErrorLog("MQTT_FAILURE", exception.toString())
}
}, object : AWSIotMqttNewMessageCallback {
override fun onMessageArrived(topic: String?, data: ByteArray?) {
Utils.showErrorLog("MQTT_MSG", topic.toString())
Utils.showErrorLog("MQTT_DATA", String(data!!))
val json = JSONObject(String(data))
if(json.has("kioskToken")){
val kioskToken=json.getString("kioskToken")
Utils.showErrorLog("KIOSK_TOKEN", kioskToken)
if(kioskToken.isNotEmpty()){
AppPreferences.saveStringToUserDefaults(context,
Constants.PrefKey.REQUEST_KIOSK_TOKEN,
kioskToken)
}
}
}
})
}
}
}
Looks like desugaring hasn't been enabled on your project. Should look like this:
android {
compileOptions {
// Support for Java 8 features
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
@tylerjroach I have added desugaring but still getting the same issue.
Are you sure that you are running AWS SDK for Android 2.73.0?
See https://github.com/eclipse/paho.mqtt.java/issues/633 and https://github.com/eclipse/paho.mqtt.java/pull/666.
This issue came from the Paho library and members on our team previously worked to help resolve this issue, which appears to be fixed in April 2020.
Upon further looking, I believe you are missing the conscrypt-android library as referenced in our iot pom: https://repo1.maven.org/maven2/com/amazonaws/aws-android-sdk-iot/2.73.0/aws-android-sdk-iot-2.73.0.pom
Our recommendation is to use our published libraries, rather than adding them directly. By adding directly, you are potentially missing transitive dependencies that are no longer being pulled in.
Hi @tylerjroach I will incorporate your suggestions and get back to you with the updated result.
Looks like desugaring hasn't been enabled on your project. Should look like this:
android { compileOptions { // Support for Java 8 features coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } }
I tried to use the latest version of coreLibraryDesugaring, but I couldn't update beyond coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.3'.
I am receiving an error while attempting to update to the latest version.
Could not resolve all files for configuration ':app:detachedConfiguration11'. Failed to transform FakeDependency.jar to match attributes {artifactType=_internal-d8-desugar-methods, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime}. Execution failed for D8BackportedMethodsGenerator: /Users/sanjaysmacbook/.gradle/android/FakeDependency.jar. Unsupported desugared library configuration version, please upgrade the D8/R8 compiler
Gradle version is : distributionUrl=https://services.gradle.org/distributions/gradle-7.4-bin.zip
Below is the Gradle code for the app.
plugins { id("com.android.application") id("org.jetbrains.kotlin.android") id ("kotlin-kapt") id("com.apollographql.apollo3") version "4.0.0-alpha.1" }
android { namespace 'com.eprintitsaas.avision.app' compileSdk 33
defaultConfig {
applicationId "com.eprintitsaas.avision.app"
minSdk 19
targetSdk 29
versionCode 1
versionName "1.0"
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
configurations.all {
resolutionStrategy {
force 'androidx.preference:preference:1.1.1'
force 'com.android.support:support-v4:25.1.1'
exclude group: "com.android.support", module: "support-core-utils"
exclude group: "com.android.support", module: "support-core-ui"
exclude group: 'com.google.code.gson', module: 'gson'
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
apollo {
service("service") {
packageName.set("com.eprintitsaas.avision.app")
}
}
}
dependencies { implementation(files("libs/commons.jar")) implementation files('libs/WorkpathLib.aar') implementation files('libs/WorkpathLib-javadoc.jar')
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.6.2")
implementation(platform("com.google.firebase:firebase-bom:32.3.1"))
implementation("com.google.firebase:firebase-crashlytics-ktx")
implementation("com.google.firebase:firebase-analytics-ktx")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:logging-interceptor:5.0.0-alpha.2")
implementation("com.squareup.retrofit2:converter-scalars:2.6.4")
implementation("com.jakewharton:butterknife:10.2.3")
kapt ("com.jakewharton:butterknife-compiler:10.2.3")
implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.1")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.1")
implementation("com.apollographql.apollo3:apollo-runtime:4.0.0-alpha.1")
implementation("com.apollographql.apollo:apollo-coroutines-support:2.5.14")
implementation("com.github.devsideal:VectorChildFinder:1.0.0")
implementation("androidx.multidex:multidex:2.0.1")
implementation ("androidx.appcompat:appcompat:1.6.1")
implementation ("com.google.android.material:material:1.9.0")
implementation ("androidx.constraintlayout:constraintlayout:2.1.4")
implementation ("com.android.support:support-core-utils:28.0.0")
implementation ("com.dropbox.core:dropbox-core-sdk:3.1.5")
implementation ("com.google.code.gson:gson:2.10.1")
implementation(platform("org.jetbrains.kotlin:kotlin-bom:1.8.0"))
implementation ("com.intuit.sdp:sdp-android:1.1.0")
implementation 'org.bouncycastle:bcpkix-jdk15on:1.67'
implementation "org.minidns:minidns-hla:0.3.2"
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'
implementation 'androidx.preference:preference:1.1.1'
implementation 'com.github.bumptech.glide:glide:4.15.1'
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.amazonaws:aws-android-sdk-iot:2.73.0'
implementation 'com.amazonaws:aws-android-sdk-core:2.73.0'
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.2.3'
}
@tylerjroach @ankpshah I am unable to create a SocketFactory object because Android API level 16 lacks TLS 1.2 support.
Hello, We pushed an update in version 2.69.0 to add TLS 1.2 support on older Android devices wherever possible. If the device does not actually support TLS1.2, we cannot resolve this issue. TLS 1.2 is the minimum TLS protocol level for all AWS API endpoints