I have the following code that works fine before obfuscation
YouTube.LiveBroadcasts.List liveBroadcastsRequest =
mYouTube.liveBroadcasts().list("id,snippet,contentDetails,status");
liveBroadcastsRequest.setMine(true);
liveBroadcastsRequest.setBroadcastType("persistent");
LiveBroadcastListResponse broadcastResponse = liveBroadcastsRequest.execute();
List<LiveBroadcast> broadcasts = broadcastResponse.getItems();
LiveBroadcast broadcast = broadcasts.get(0);
But in release version with obfuscation the last line of the code throws the following exception
java.lang.ClassCastException: com.google.api.client.util.ArrayMap cannot be cast to com.google.api.services.youtube.model.LiveBroadcast
I suppose that the issue happens because my obfuscation somehow breaks gson deserialization in google api, but I cannot find how to modify my proguard rules to make it working.
Current obfuscation rules
-keep class sun.misc.Unsafe { *; }
-dontwarn sun.misc.Unsafe
-keepattributes *Annotation*
-keep class com.google.** { *; }
-keep class com.google.api.services.youtube.model.** { *; }
-dontwarn com.google.**
Any help will be appreciated
Found a correct answer here
I needed to keep the com.google.api.client.util.Key annotation from obfuscation.
-keepclassmembers class * {
#com.google.api.client.util.Key <fields>;
}
-keepattributes Signature,RuntimeVisibleAnnotations,AnnotationDefault
Thanks anyway.
Related
I use ProGuard and Joda Time in my Android application (of course, I use a version optimized for Android: https://github.com/dlew/joda-time-android). I ran into the problem that with optimization and obfuscation turned on, I get an error when I try to use PeriodFormat:
java.util.MissingResourceException: can't find resource for bundle java.util.PropertyResourceBundle, key PeriodFormat.space
I compared the contents of the APK when building with and without proguard and saw that the org/joda/time/format directory in the non-optimized version contains 15 properties files, and only 9 in the optimized version. In these files I saw the PeriodFormat.space keys, so leaves no doubt that the exception caused by the loss of these files.
How to configure proguard so that the contents of this directory are transferred to the optimized APK without any optimizations?
I already use the following rules for Joda Time:
-dontwarn org.joda.convert.**
-dontwarn org.joda.time.**
-keep class org.joda.** { *; }
-keep interface org.joda.** { *; }
-keepdirectories org.joda.**
However, they are not enough, because the files still disappear.
java.util.MissingResourceException: can't find resource for bundle
java.util.PropertyResourceBundle, key PeriodFormat.space
Don't
-keep class org.joda.** { *; }
-keep interface org.joda.** { *; }
Do
-keep class org.joda.time.** { *; }
-keep interface org.joda.time.** { *; }
Your proguard will be
-dontwarn org.joda.convert.**
-dontwarn org.joda.time.**
-keep class org.joda.time.** { *; }
-keep interface org.joda.time.** { *; }
Read -keep options.
I am having problems with GSON on Android with Proguard.
APK is compiled, installed on phone.
Application is not crashing, it is just not parsing object correctly.
I log all the data and it is like that:
I get correct string with data to parse.
(CookieValue is correct)
Token token = new Gson().fromJson(cookieValue, Token.class);
After this line, I am logging this object and it is having only null values inside.
My Proguard GSON:
# 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
-dontwarn sun.misc.**
-keep class sun.misc.Unsafe { *; }
-keep class com.google.gson.stream.** { *; }
-keep class com.google.gson.examples.android.model.** { *; }
-keep class * implements com.google.gson.TypeAdapterFactory
-keep class * implements com.google.gson.JsonSerializer
-keep class * implements com.google.gson.JsonDeserializer
-keep public class com.google.gson
Token rules:
-dontwarn com.project.package.model.oauth.**
-keep,allowshrinking class com.project.package.oauth.Token { *; }
Yes, I have tried this configuration https://github.com/google/gson/blob/master/examples/android-proguard-example/proguard.cfg
Any suggestions?
In this line:
- keep,allowshrinking class com.project.package.oauth.Token { *; }
Do you actually have a space between the dash and keep? If so, take that out and see if it helps.
You might also want to remove the space after the dash in the previous dontwarn line, as well.
You can find it in my collection :
https://github.com/thientvse/awesome-mobile-collections/blob/master/README.md
It will help you config almost lib in proguard file.
I hope it will help your problem!
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.