Home > Blockchain >  Android java.lang.NoSuchFieldError when using the AWS Amplify API
Android java.lang.NoSuchFieldError when using the AWS Amplify API

Time:10-25

I am writing an app using both the aws android api and the aws Amplify api. The issue occurs when I am using methods from AWSKinesisVideoClient (look at the line starting with Caused by).

E/AndroidRuntime: FATAL EXCEPTION: AsyncTask #1
Process: com.appliedstructures.myapp_v002, PID: 32474
java.lang.RuntimeException: An error occurred while executing doInBackground()
    at android.os.AsyncTask$4.done(AsyncTask.java:399)
    at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:383)
    at java.util.concurrent.FutureTask.setException(FutureTask.java:252)
    at java.util.concurrent.FutureTask.run(FutureTask.java:271)
    at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:289)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
    at java.lang.Thread.run(Thread.java:919)
 Caused by: java.lang.NoSuchFieldError: No instance field timeOffset of type I in class Lcom/amazonaws/services/kinesisvideo/AWSKinesisVideoClient; or its superclasses (declaration of 'com.amazonaws.services.kinesisvideo.AWSKinesisVideoClient' appears in /data/app/com.appliedstructures.myapp_v002-ktjX0i0uX6YfDy0RwrPWFA==/base.apk)
    at com.amazonaws.services.kinesisvideo.AWSKinesisVideoClient.invoke(AWSKinesisVideoClient.java:1532)
    at com.amazonaws.services.kinesisvideo.AWSKinesisVideoClient.describeSignalingChannel(AWSKinesisVideoClient.java:653)
    at com.appliedstructures.myapp_v002.ui.home.HomeFragment$InfoUpdaterTask.doInBackground(HomeFragment.java:141)
    at com.appliedstructures.myapp_v002.ui.home.HomeFragment$InfoUpdaterTask.doInBackground(HomeFragment.java:102)

However, when I manually inspect the code in that class, there is clearly a field called timeOffset. I read online that a source of this issue might be android's ProGuard (since it can remove unused code and accidentally remove this field as well). However, in my gradle.build I directly specified minifyEnabled false in both release and debug.

here is my gradle.build (root):

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
    repositories {
        google()
        jcenter()
        mavenCentral()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:7.0.3"

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

And here is gradle.build (app):

plugins {
    id 'com.android.application'
}

android {
    compileSdk 30

    defaultConfig {
        applicationId "com.appliedstructures.myapp_v002"
        minSdk 24
        targetSdk 30
        versionCode 1
        versionName "1.0"
        android
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    packagingOptions {
        exclude 'com/fasterxml/jackson/databind/cfg/VERSION.txt'
        exclude 'com/fasterxml/jackson/core/json/VERSION.txt'
        exclude 'META-INF/DEPENDENCIES'
    }

    buildTypes {
        release {
            minifyEnabled false
            //proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
        debug {
            minifyEnabled false
        }
    }
    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
    buildFeatures {
        viewBinding true
    }
}

dependencies {
    //builAmplify dependencies
    implementation 'com.amplifyframework:core:1.28.1'
    implementation 'com.amplifyframework:aws-auth-cognito:1.28.1'

    //aws dependencies
    def aws_version = '2.16.13'
    implementation ("com.amazonaws:aws-android-sdk-kinesisvideo:$aws_version@aar") { transitive = true }
    implementation ("com.amazonaws:aws-android-sdk-kinesisvideo-signaling:$aws_version@jar") { transitive = true }
    implementation ("com.amazonaws:aws-android-sdk-mobile-client:$aws_version@aar") { transitive = true }
    implementation ("com.amazonaws:aws-android-sdk-auth-userpools:$aws_version@aar") { transitive = true }

    //android default dependencies
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'com.google.android.material:material:1.4.0'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.1'
    implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.3.1'
    implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.3.1'
    implementation 'androidx.navigation:navigation-fragment:2.3.5'
    implementation 'androidx.navigation:navigation-ui:2.3.5'
    testImplementation 'junit:junit:4. '
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

    //support for Java 8 features
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}

So what is the source of the problem and how can it be fixed (refreshing gradle, and restarting android studio did not work)?

Edit: Here is the exact code snippet that causes the issue:

AWSKinesisVideoClient client;

try {
    client = getAwsKinesisVideoClient();
} catch (Exception e) {
    return FAILED;
}

DescribeSignalingChannelResult describeResult = client.describeSignalingChannel(
        new DescribeSignalingChannelRequest().withChannelARN(channelName));
            

CodePudding user response:

To write Android apps that invoke AWS Services, consider using the new enter image description here

Code for this is:

package com.example.androidkinvideo

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.Toast
import aws.sdk.kotlin.runtime.auth.credentials.StaticCredentialsProvider
import aws.sdk.kotlin.services.kinesisvideo.KinesisVideoClient
import aws.sdk.kotlin.services.kinesisvideo.model.DescribeStreamRequest
import kotlinx.coroutines.runBlocking

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
    }

    fun showARN(view: View) = runBlocking{

        val staticCredentials = StaticCredentialsProvider {
            accessKeyId = "AKIA33JWYxxxxxxxxxxxxxxx"
            secretAccessKey = "/zyyrAnarbnxxxxxxxxxxxxxxxx"
        }

        val vidClient = KinesisVideoClient{
            region = "us-east-1"
            credentialsProvider = staticCredentials
        }

        val request = DescribeStreamRequest {
            streamName = "ExampleStream"
        }

        val streamResponse = vidClient.describeStream(request)
        val arnVal = streamResponse.streamInfo?.streamArn
        if (arnVal != null) {
            showToast(arnVal)
        }
    }

    fun showToast(value:String){
        val toast = Toast.makeText(applicationContext, value, Toast.LENGTH_SHORT)
        toast.setMargin(50f, 50f)
        toast.show()
    }
}

Gradle Build:

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

android {

    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
        coreLibraryDesugaringEnabled true
    }

    lintOptions {
        abortOnError false
    }
    kotlinOptions {
        jvmTarget = "1.8"
    }

    compileSdkVersion 30
    buildToolsVersion "30.0.0"

    packagingOptions {
        exclude 'META-INF/DEPENDENCIES'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/license.txt'
        exclude 'META-INF/NOTICE'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/ASL2.0'
        exclude("META-INF/*.kotlin_module")
    }

    defaultConfig {
        applicationId "com.example.aws"
        minSdkVersion 26
        targetSdkVersion 30
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: "libs", include: ["*.jar"])
    api("aws.sdk.kotlin:kinesisvideo:0.6.0-alpha")
    api("aws.sdk.kotlin:dynamodb:0.6.0-alpha")
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
    implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
    implementation 'androidx.core:core-ktx:1.6.0'
    implementation 'androidx.appcompat:appcompat:1.3.1'
    implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'androidx.test.ext:junit:1.1.3'
    androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
}
  • Related