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):
@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.
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.For me the error always came from
SignerFactory.createSigner. So, I'm guessing that R8 is not following thesignerTypeString to class mappings inSignerFactory.I assume then we might also find
QueryStringSignerandNoOpSignerhas similar issues withenableR8.fullMode=true.