I am using Volley and Gson in my project. The project is a Lib project. When I use my Lib in a demo project, the Volley always throw error response with message: "org.json.JSONException: End of input at character 0" and never has success response. I guess it is caused by ProGuard. The weird thing is when I set "minifyEnabled" in either Lib or the Demo project, everything works good. But when I set "minifyEnabled" in both Lib and Demo, volley will always fail. Does anyone now why this happen?
Sorry for missing the content...
this is the error volley throw:
org.json.JSONException: End of input at character 0
and this is my ProGuard for volley and Gson:
## ----------------------------------
## Gson
## ----------------------------------
-keepattributes Signature
-keepattributes *Annotation*
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.** { *; }
-keep class com.google.gson.stream.** { *; }
## ----------------------------------
## Glide
## ----------------------------------
-keep class com.bumptech.glide.** {*;}
## -------------------------------------------
## volley
## -------------------------------------------
-keepclassmembers,allowshrinking,allowobfuscation class com.android.volley.NetworkDispatcher {
void processRequest();
}
-keepclassmembers,allowshrinking,allowobfuscation class com.android.volley.CacheDispatcher {
void processRequest();
}
-keep class com.android.volley.** {*;}
-keep class com.android.volley.toolbox.Volley
-keepclassmembers class com.android.volley.toolbox.Volley { *; }
-keep class com.android.volley.toolbox.** {*;}
-keep class com.android.volley.Response$* { *; }
-keep class com.android.volley.Request$* { *; }
-keep class com.android.volley.RequestQueue$* { *; }
-keep class com.android.volley.toolbox.HurlStack$* { *; }
-keep class com.android.volley.toolbox.ImageLoader$* { *; }
-keep class org.apache.http.** {*;}
The important thing is this error only happened if both Lib and Demo are obfuscated at the same time. Obfuscate with either Lib or Demo would not have this issue.
Anyone help? I am 100% sure I keep all my model classes in the ProGuard file.
2019-03-18 14:38:15.635 11276-11276 W/System.err: com.a.a.m: org.json.JSONException: End of input at character 0 of
2019-03-18 14:38:15.635 11276-11276 W/System.err: at com.a.a.a.k.a(Unknown Source:32)
While the com.a.a.a.k is "com.android.volley.toolbox.JsonObjectRequest"
put this rules in proguard,
-keep class com.android.volley.** { *; }
-keep class org.apache.commons.logging.**
-keepattributes *Annotation*
-dontwarn org.apache.**
Add following lines in your proguard-rules.pro, which you can find under Gradle Script
-keepclassmembers,allowshrinking,allowobfuscation class com.android.volley.NetworkDispatcher {
void processRequest();
}
-keepclassmembers,allowshrinking,allowobfuscation class com.android.volley.CacheDispatcher {
void processRequest();
}
You can also refer this link
Update
Then you should add these rules in your proguard-rules.pro of your library project. If you see that iamge near proguard-rules.pro it is written that this file is for app module, there should be an another proguard-rules.pro for your library module add rule there too.
Try using following configuration in your build.gradle.
android {
...
useLibrary 'org.apache.http.legacy'
}
I had similar issue with volley but different error, above configuration solved my issue. The root cause was Gradle plugin does not include all optional libraries by default anymore.
Related
The goal is to deploy an application with obfuscation and minification applied. Usual builds without minification work fine. But when minifyEnabled is switched to true, everything compiles too, but all Volley requests fail with error callback (onErrorResponse) regardless on successful result.
Minification config in build.gradle:
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
debug {
debuggable true
}
}
proguard-rules.pro:
##---------------Begin: proguard configuration for Gson ----------
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON #Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
#-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
# Prevent proguard from stripping interface information from TypeAdapterFactory,
# JsonSerializer, JsonDeserializer instances (so they can be used in #JsonAdapter)
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
##---------------End: proguard configuration for Gson ----------
##---------------Begin: proguard configuration for Spongy Castle ----------
-keep class org.spongycastle.crypto.* {*;}
-keep class org.spongycastle.crypto.digests.* {*;}
-keep class org.spongycastle.crypto.encodings.* {*;}
-keep class org.spongycastle.crypto.engines.* {*;}
-keep class org.spongycastle.crypto.macs.* {*;}
-keep class org.spongycastle.crypto.modes.* {*;}
-keep class org.spongycastle.crypto.paddings.* {*;}
-keep class org.spongycastle.crypto.params.* {*;}
-keep class org.spongycastle.crypto.prng.* {*;}
-keep class org.spongycastle.crypto.signers.* {*;}
-keep class org.spongycastle.jcajce.provider.digest.** {*;}
-keep class org.spongycastle.jcajce.provider.keystore.** {*;}
-keep class org.spongycastle.jcajce.provider.symmetric.** {*;}
-keep class org.spongycastle.jcajce.spec.* {*;}
-keep class org.spongycastle.jce.** {*;}
-dontwarn javax.naming.**
##---------------End: proguard configuration for Spongy Castle ----------
# Configuration for Guava 18.0
#
# disagrees with instructions provided by Guava project: https://code.google.com/p/guava-libraries/wiki/UsingProGuardWithGuava
-keep class com.google.common.io.Resources {
public static <methods>;
}
-keep class com.google.common.collect.Lists {
public static ** reverse(**);
}
-keep class com.google.common.base.Charsets {
public static <fields>;
}
-keep class com.google.common.base.Joiner {
public static com.google.common.base.Joiner on(java.lang.String);
public ** join(...);
}
-keep class com.google.common.collect.MapMakerInternalMap$ReferenceEntry
-keep class com.google.common.cache.LocalCache$ReferenceEntry
# http://stackoverflow.com/questions/9120338/proguard-configuration-for-guava-with-obfuscation-and-optimization
-dontwarn javax.annotation.**
-dontwarn javax.inject.**
-dontwarn sun.misc.Unsafe
# Guava 19.0
-dontwarn java.lang.ClassValue
-dontwarn com.google.j2objc.annotations.Weak
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
# Security classes for keystore support
-dontwarn java.awt.**, javax.security.**, java.beans.**
# Volley
-dontwarn com.android.volley.**
-dontwarn com.android.volley.error.**
-keep class com.android.volley.** { *; }
-keep class com.android.volley.toolbox.** { *; }
-keep class com.android.volley.Response$* { *; }
-keep class com.android.volley.Request$* { *; }
-keep class com.android.volley.RequestQueue$* { *; }
-keep class com.android.volley.toolbox.HurlStack$* { *; }
-keep class com.android.volley.toolbox.ImageLoader$* { *; }
-keep interface com.android.volley.** { *; }
-keep class org.apache.commons.logging.*
All used dependencies:
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.google.code.gson:gson:2.7'
compile 'com.android.volley:volley:1.0.0'
compile 'com.google.guava:guava:19.0'
compile 'org.apache.directory.studio:org.apache.commons.io:2.4'
compile 'com.madgag.spongycastle:core:1.54.0.0'
compile 'com.madgag.spongycastle:prov:1.54.0.0'
compile 'com.madgag.spongycastle:pkix:1.54.0.0'
compile 'com.madgag.spongycastle:pg:1.54.0.0'
And in addition to Volley failures, EventBus from Guava doesn't work correctly too (subscribe events are not fetching). Do we have any solutions for these troubles? Should I add any additional information here?
Should admit, that even with all information provided, my question was very difficult to analyze, because of many possible sources of described errors.
I'll begin from the end of my question. Guava didn't work correctly, because ProGuard just excluded Guava's Subscribe-methods from my code to be packed. ProGuard removes unused code, and as far as Subscribe-methods are analyzed as unused (even IDE don't highlight them as used ones) ProGuard has decided to remove these methods. To solve this issue, we should keep Subscribe-methods from ProGuard's processing:
# Keep subscribe-methods from deletion
-keepclassmembers class ** {
#com.google.common.eventbus.Subscribe <methods>;
}
And my first problem - when Volley always calls onErrorResponse callbacks in all requests being fired. I used a custom deserializer for Json-repsonses which also checks, if server has provided some required fields (marked with a corresponding annotation). And, of course, ProGuard by default could not work correctly with these annotations and deserializer - that's why I had to keep these entities too:
# To make right deserialization
-keepclassmembers class ** {
#com.some.package.server.JsonDeserializerWithOptions$FieldRequired public *;
}
-keep #interface com.some.package.server.JsonDeserializerWithOptions$FieldRequired
-keep class com.some.package.server.JsonDeserializerWithOptions
Its difficult the pinpoint any error with the logs, however you should try it without using proguard. skip the proguard file syntax and see if it works fine.
Make sure you have multidex enabled, else your project will fail to execute.
android {
compileSdkVersion 21
buildToolsVersion "21.1.0"
defaultConfig {
...
minSdkVersion 14
targetSdkVersion 21
...
// Enabling multidex support.
multiDexEnabled true
}
...
}
dependencies {
compile 'com.android.support:multidex:1.0.0'
}
More details : https://developer.android.com/studio/build/multidex.html
I try using Proguard in android studio, but seems like Proguard is not obfuscating the class name, for example, my app structure, and the config:
and config
but when i try trigger the exception in the app:
the exception is listed in ADB console:
only the methods are obfuscated, the MainActivity.class is not
This is an expected behaviour because the class is an activity!
All classes that are mentioned in AndroidManifest.xml have to keep their names (activities, services, providers, receivers, application, instrumentation). Otherwise the system won't be able to find them.
Gradle build automatically generates some rules for your ProGuard configuration to achieve this. It scans AndroidManifest.xml and adds rules for each class found there.
If you want to see all the rules that are used, add this line to your ProGuard rules:
-printconfiguration "build/outputs/mapping/configuration.txt"
It will create configuration.txt file containing all the rules.
There should be something like this:
# view AndroidManifest.xml #generated:50
-keep class com.github.browep.proguard.MainActivity {
<init>(...);
}
I was facing the same problems,
After updating my Android plugin for Gradle, Proguard stop obfuscating my utility and other class files.
After few searching, I found that Android studio gradle now uses newer version of Proguard.
And according to this stack-overflow answer, which stated that:
proguard automatically add rules specific for android/google package.
Therefore, After few rule changes in my app, Proguard obfuscated the class names again.
Old proguard-rules.pro:
#support-v4
##link https://stackoverflow.com/questions/18978706/obfuscate-android-support-v7-widget-gridlayout-issue
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
#support-v7
-dontwarn android.support.v7.**
-keep class android.support.v7.** { *; }
#https://stackoverflow.com/a/34895791/4754141
-keep class !android.support.v7.view.menu.**
-keep interface android.support.v7.* { *; }
#support design
##link https://stackoverflow.com/a/31028536
-dontwarn android.support.design.**
-keep class android.support.design.** { *; }
-keep interface android.support.design.** { *; }
-keep public class android.support.design.R$* { *; }
#error : Note: the configuration refers to the unknown class 'com.google.vending.licensing.ILicensingService'
#solution : #link https://stackoverflow.com/a/14463528
-dontnote com.google.vending.licensing.ILicensingService
-dontnote **ILicensingService
#updating to Gradle 2.14.1 caused error : https://stackoverflow.com/q/17141832/4754141
-keepattributes EnclosingMethod
#render script
##link https://stackoverflow.com/questions/22161832/renderscript-support-library-crashes-on-x86-devices
-keepclasseswithmembernames class * { native <methods>; }
-keep class android.support.v8.renderscript.** { *; }
New proguard-rules.pro:
#https://stackoverflow.com/a/41901653/4754141
#https://stackoverflow.com/a/23840049/4754141
-keep class android.support.** { *; }
-keep interface android.support.** { *; }
If I build my app in debug it works perfectly. However, when I build for release with proguard, I get several errors and then the build fails. The error summary:
Warning:there were 445 unresolved references to classes or interfaces.
Warning:there were 13 instances of library classes depending on program classes.
I modified my proguard-rules.txt file as shown below. This allowed the build to succeed, but when I install the app, the amazon downloads do not work (works in the debug version).
-keep class org.xmlpull.v1.**
-keep class org.apache.http.**
-keep class org.ietf.jgss.**
-keep class com.amazonaws.services.**
-keep class org.w3c.dom.bootstrap.**
-dontwarn org.xmlpull.v1.**
-dontwarn org.apache.http.**
-dontwarn org.ietf.jgss.**
-dontwarn com.amazonaws.services.**
-dontwarn org.w3c.dom.bootstrap.**
Any suggestions as to how I can get this fixed please?
Update:
Have narrowed it down to a GSON/JSONPARSER issue. For the release version, JSONPARSER does not convert downloaded json to a supplied class like it does in debug. The GSON proguard rules (see update 2 ) have also been added but the issue persists.
-keep class org.apache.commons.logging.** { *; }
-keep class com.amazonaws.services.sqs.QueueUrlHandler { *; }
-keep class com.amazonaws.javax.xml.transform.sax.* { public *; }
-keep class com.amazonaws.javax.xml.stream.** { *; }
-keep class com.amazonaws.services.**.model.*Exception* { *; }
-keep class com.amazonaws.internal.** { *; }
-keep class org.codehaus.** { *; }
-keep class org.joda.convert.* { *; }
-keepattributes Signature,*Annotation*,EnclosingMethod
-keepnames class com.fasterxml.jackson.** { *; }
-keepnames class com.amazonaws.** { *; }
-dontwarn com.amazonaws.auth.policy.conditions.S3ConditionFactory
-dontwarn org.joda.time.**
-dontwarn com.fasterxml.jackson.databind.**
-dontwarn javax.xml.stream.events.**
-dontwarn org.codehaus.jackson.**
-dontwarn org.apache.commons.logging.impl.**
-dontwarn org.apache.http.conn.scheme.**
-dontwarn org.apache.http.annotation.**
-dontwarn org.ietf.jgss.**
-dontwarn org.w3c.dom.bootstrap.**
-dontwarn org.xmlpull.v1.**
-dontwarn com.amazonaws.services.**
-libraryjars libs/aws-android-sdk-1.7.1.1-core.jar
-libraryjars libs/aws-android-sdk-1.7.1.1-s3.jar
-libraryjars libs/gson-2.2.4.jar
-libraryjars libs/ksoap2-android-assembly-3.3.0-jar-with-dependencies.jar
Update 2
# Gson uses generic type information stored in a class file when working with fields. Proguard
# removes such information by default, so configure it to keep all of it.
-keepattributes Signature
# For using GSON #Expose annotation
-keepattributes *Annotation*
# Gson specific classes
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
Finally solved. GSON could not convert my JSON into a class using the fromJson method as proguard had obfuscated my class's fields. I had to add for each of my classes used during json deserialization:
-keepclassmembers class fully.qualified.path.to.class$innerclass {
private <fields>;
}
As per usual, no mention of this in the GSON docs. This was a project I took over - I personally have never used GSON and wont do so in future.
A few notes to those facing similar issues:
Always make sure when you use a library to include all the
recommended (by the library - see their web pages) entries in your
proguard-rules.text file.
They have mentioned in the comments in the second last line of update2.
# Application classes that will be serialized/deserialized over Gson
-keep class com.google.gson.examples.android.model.** { *; }
Change the last line to your actual path inside code to classes that will be serialized. Don't copy paste as it is. Example:
-keep class com.myclass.model.** { *; }
That worked for me.
I have an Android app which uses Google Volley as my download broker. I just tried to use ProGuard to obfuscate the code, and find out the volley download starts failing at runtime.
Here's my ProGuard config:
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class com.actionbarsherlock.** { *; }
-keep interface com.actionbarsherlock.** { *; }
-keep class com.android.volley.** { *; }
-keep interface com.android.volley.** { *; }
-keepattributes *Annotation*
-dontwarn org.apache.**
and here is the error I saw in the code:
Async download FAILED. Exception message: The chosen LogFactory implementation does not extend LogFactory. Please check your configuration. (Caused by java.lang.ClassCastException: The application has specified that a custom LogFactory implementation should be used but Class 'org.apache.commons.logging.impl.LogFactoryImpl' cannot be converted to 'a.a.a.b.c'. Please check the custom implementation. Help can be found #http://commons.apache.org/logging/troubleshooting.html.)
I was wondering if I did some proguard config caused some dependency problem. Please help out.
The Apache logging library uses some reflection on its log factories. Keeping their names should be sufficient:
-keep class org.apache.commons.logging.**
Side-note on your configuration: -keep class ..... always implies -keep interface ....., so you can leave out the latter.
I want to use Proguard mainly for obfuscation reasons.
My problem is that I have three libraries, Twitter4J and two signpost libraries. These libraries caused errors when I tried to create an signed APK. To get over this I put the following in the proguard.config file...
-dontwarn org.apache.commons.codec.binary.**
-dontwarn org.slf4j.**
-dontwarn com.sun.syndication.io.**
-dontwarn com.sun.syndication.feed.synd.*
While this got rid of the errors in the console, when i loaded my signed APK onto my mobile phone it instantly crashed. The DDMS said this was due to a class not found in Twitter4J.
Getting rid of the "dontwarns" above did not help. Neither did adding dontshrink dontoptimise.
I would like Proguard to completely ignore the libraries (as they are open source anyway). Is this possible?
Try this:
-keep class javax.** { *; }
-keep class org.** { *; }
-keep class twitter4j.** { *; }
Cf post from #CaspNZ:
Android Proguard with external jar
You should be able to add to the proguard.cfg the following lines to exclude all classes within a package (and subpackages)
-keep class org.apache.commons.codec.binary.**
-keep interface org.apache.commons.codec.binary.**
-keep enum org.apache.commons.codec.binary.**
-keep class org.slf4j.**
-keep interface org.slf4j.**
-keep enum org.slf4j.**
-keep class com.sun.syndication.io.**
-keep interface com.sun.syndication.io.**
-keep enum com.sun.syndication.io.**
-keep class com.sun.syndication.feed.synd.**
-keep interface com.sun.syndication.feed.synd.**
-keep enum com.sun.syndication.feed.synd.**
I'd like to add that you should sync your project with Gradle files after adding proguard rules, otherwise they may not work.