Aws-sdk-android: [S3] "android.enableR8.fullMode=true" makes AmazonS3Client not able to create a instance of S3Signer

Created on 21 Feb 2019  路  7Comments  路  Source: aws-amplify/aws-sdk-android

Describe the bug

Adding the flag android.enableR8.fullMode=true breaks the create of instance of the S3Signer.

W: java.lang.IllegalStateException: Cannot create an instance of com.amazonaws.services.s3.internal.S3Signer
W:     at com.amazonaws.auth.SignerFactory.createSigner(SignerFactory.java:121)
W:     at com.amazonaws.auth.SignerFactory.lookupAndCreateSigner(SignerFactory.java:104)
W:     at com.amazonaws.auth.SignerFactory.getSigner(SignerFactory.java:79)
W:     at com.amazonaws.AmazonWebServiceClient.computeSignerByServiceRegion(AmazonWebServiceClient.java:402)
W:     at com.amazonaws.AmazonWebServiceClient.computeSignerByURI(AmazonWebServiceClient.java:374)
W:     at com.amazonaws.AmazonWebServiceClient.setEndpoint(AmazonWebServiceClient.java:218)
W:     at com.amazonaws.services.s3.AmazonS3Client.setEndpoint(AmazonS3Client.java:672)
W:     at com.amazonaws.services.s3.AmazonS3Client.init(AmazonS3Client.java:606)
W:     at com.amazonaws.services.s3.AmazonS3Client.<init>(AmazonS3Client.java:409)
W:     at com.amazonaws.services.s3.AmazonS3Client.<init>(AmazonS3Client.java:361)
W:     at com.amazonaws.services.s3.AmazonS3Client.<init>(AmazonS3Client.java:322)
...
W:     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:428)
W:     at java.util.concurrent.FutureTask.run(FutureTask.java:237)
W:     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1133)
W:     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:607)
W:     at java.lang.Thread.run(Thread.java:761)
W: Caused by: java.lang.InstantiationException: java.lang.Class<com.amazonaws.services.s3.internal.S3Signer> has no zero argument constructor
W:     at java.lang.Class.newInstance(Native Method)
W:     at com.amazonaws.auth.SignerFactory.createSigner(SignerFactory.java:118)
W:  ... 28 more

To Reproduce

Add this on your grade.properties:

android.enableR8=true
android.enableR8.fullMode=true //Remove this line to stop the problem

And call this:

val s3Client = AmazonS3Client(
  BasicSessionCredentials(awsAccessKey, awsSecretKey, sessionToken), 
  clientConfig)

Which AWS service(s) are affected?
S3

Environment Information (please complete the following information):

  • AWS Android SDK Version: Any but also happening on 2.12.0.
  • Kotlin Version: 1.3.21
  • Gradle: 5.2.1
  • Device: Any
  • Android Version: Any
  • Specific to simulators: No
Core Needs Info from Requester Usage Question closing-soon-if-no-response

Most helpful comment

I found a similar issue but also found that R8 fullMode was also removing AWS4Signer. But, I found that adding the following keep rules seemed to resolve the issue.

-keep class com.amazonaws.auth.AWS4Signer
-keep class com.amazonaws.services.s3.internal.S3Signer

For me the error always came from SignerFactory.createSigner. So, I'm guessing that R8 is not following the signerType String to class mappings in SignerFactory.

// SignerFactory.java:110
private static Signer createSigner(String signerType,
            final String serviceName) {
        Class<? extends Signer> signerClass = SIGNERS.get(signerType);

I assume then we might also find QueryStringSigner and NoOpSigner has similar issues with enableR8.fullMode=true.

All 7 comments

@ppamorim Sorry for the inconvenience caused. My understanding about R8 is that, R8 is a java program shrinking and minification tool that converts java byte code to optimized dex code. R8 is a Proguard replacement for whole-program optimization, shrinking and minification. R8 uses the Proguard keep rule format for specifying the entry points for an application.

Are you using R8 in conjunction with the rules specified through Proguard. If so, can you show us the Proguard configuration file.

Our SDK does not support obfuscation. We have a recommendation in Proguard.md to not obfuscate the SDK classes.

For example:

# Class names are needed in reflection
-keepnames class com.amazonaws.**
-keepnames class com.amazon.**
# Request handlers defined in request.handlers
-keep class com.amazonaws.services.**.*Handler
# The following are referenced but aren't required to run
-dontwarn com.fasterxml.jackson.**
-dontwarn org.apache.commons.logging.**
# Android 6.0 release removes support for the Apache HTTP client
-dontwarn org.apache.http.**
# The SDK has several references of Apache HTTP client
-dontwarn com.amazonaws.http.**
-dontwarn com.amazonaws.metrics.**

Have you specified this in your Proguard rules?

I added the following to my app's gradle.properties file

android.enableR8=true
android.enableR8.fullMode=true

along with the Proguard rules to not obfuscate and I was able to upload and download files to S3 using AmazonS3Client without any exception.

Is there a specific gradle build target that you run to get your apk file?

@kvasukib I am still getting the error even including these rules on Proguard.md, despite the build type (debug or release).

build.gradle

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
apply plugin: 'checkstyle'
apply plugin: 'realm-android'
apply plugin: 'com.google.firebase.firebase-perf'
apply plugin: 'com.getkeepsafe.dexcount'
apply plugin: 'io.fabric'

android {

  compileSdkVersion Integer.parseInt(project.ANDROID_COMPILE_SDK_VERSION)
  buildToolsVersion project.ANDROID_BUILD_TOOLS_VERSION

  defaultConfig {
    applicationId XXX
    versionCode Integer.parseInt(project.VERSION_CODE)
    versionName project.VERSION_NAME
    targetSdkVersion Integer.parseInt(project.ANDROID_TARGET_SDK_VERSION)
    minSdkVersion minSdk
    vectorDrawables.useSupportLibrary = true
    testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    multiDexEnabled true
    dexOptions {
      javaMaxHeapSize "4g"
    }
    ndk {
      buildTypes {
        debug {
          abiFilters 'x86', 'armeabi-v7a', 'arm64-v8a'
        }
        release {
          abiFilters 'armeabi-v7a', 'arm64-v8a'
        }
      }
    }

  }

  buildTypes {
    debug {
      debuggable true
      jniDebuggable true
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules-debug.pro'
      testProguardFiles 'proguard-rules-test.pro'
    }
    release {
      debuggable false
      jniDebuggable false
      minifyEnabled true
      proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
    }
  }

  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }

  sourceSets {
    main.java.srcDirs += 'src/main/kotlin'
    test.java.srcDirs += 'src/test/kotlin'
  }

  lintOptions {
    abortOnError false
    checkReleaseBuilds false
    checkAllWarnings false
    warningsAsErrors false
    textOutput "stdout"
    disable "UnusedResources"              // Unused will be removed on release
    disable "IconExpectedSize"             // Using the material icons provided from Google
    disable "GoogleAppIndexingApiWarning"  // We might want to index our app later
    disable "InvalidPackage"               // Butterknife, Okio and Realm
    disable "ResourceType"                 // Annotation binding
    disable "GradleDependency"
    disable "NewerVersionAvailable"
    disable 'InvalidPackage'
  }

  packagingOptions {
    exclude "**/*.txt"
    exclude 'META-INF/DEPENDENCIES.txt'
    exclude 'META-INF/LICENSE.txt'
    exclude 'META-INF/NOTICE.txt'
    exclude 'META-INF/NOTICE'
    exclude 'META-INF/LICENSE'
    exclude 'META-INF/DEPENDENCIES'
    exclude 'META-INF/notice.txt'
    exclude 'META-INF/license.txt'
    exclude 'META-INF/dependencies.txt'
    exclude 'META-INF/*.kotlin_module'
    exclude 'META-INF/LGPL2.1'
    exclude 'META-INF/ASL2.0'
    exclude 'META-INF/services/javax.annotation.processing.Processor'
    exclude 'META-INF/services/com.fasterxml.jackson.core.JsonFactory'
    exclude 'META-INF/services/com.fasterxml.jackson.core.ObjectCodec'
    exclude 'META-INF/proguard/androidx-annotations.pro'
  }

  splits {
    abi {
      enable false
      reset()
      include 'armeabi-v7a', 'arm64-v8a', 'x86', 'x86_64'
    }
  }

}


dependencies {
  #private...
}

buildscript {
  dependencies {
    classpath classpaths.kotlinGradlePlugin
  }
}

task checkstyle(type: Checkstyle) {
  configFile file('../config/checkstyle/checkstyle.xml')
  source 'src/main/kotlin'
  include '**/*.java'
  include '**/*.kt'
  exclude '**/gen/**'
  classpath = files()
}

apply plugin: 'com.google.gms.google-services'

@ppamorim Thank you for posting the build.gradle. I will try with your settings in my app to see if the issue can be reproduced.

I found a similar issue but also found that R8 fullMode was also removing AWS4Signer. But, I found that adding the following keep rules seemed to resolve the issue.

-keep class com.amazonaws.auth.AWS4Signer
-keep class com.amazonaws.services.s3.internal.S3Signer

For me the error always came from SignerFactory.createSigner. So, I'm guessing that R8 is not following the signerType String to class mappings in SignerFactory.

// SignerFactory.java:110
private static Signer createSigner(String signerType,
            final String serviceName) {
        Class<? extends Signer> signerClass = SIGNERS.get(signerType);

I assume then we might also find QueryStringSigner and NoOpSigner has similar issues with enableR8.fullMode=true.

Any idea how to solve this?

@ppamorim Have you added the classes that are failing in the proguard rules file like how @marukami did? Are you encountering any other failures besides the *Signer classes?

This issue has been automatically closed because of inactivity. Please open a new issue if are still encountering problems.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nsadiq-radpits picture nsadiq-radpits  路  3Comments

osugikoji picture osugikoji  路  4Comments

logo17 picture logo17  路  3Comments

devxpy picture devxpy  路  4Comments

zgao67 picture zgao67  路  4Comments