ProGuard not working as expected after Android Studio update - android

Since I updated Android Studio to version 1.2.1.1 I have the following problem:
Whenever I build a release version / build variant of my app, I get a NoClassDefFoundError on the Adjust library I have included in the project as a library module.
The stracktrace:
java.lang.NoClassDefFoundError: com.adjust.sdk.AdjustConfig
at de.myapp.GlobalApp.prepareAdjust(GlobalApp.java:111)
at de.myapp.GlobalApp.onCreate(GlobalApp.java:71)
at android.app.Instrumentation.callApplicationOnCreate(Instrumentation.java:999)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4151)
at android.app.ActivityThread.access$1300(ActivityThread.java:130)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1255)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4745)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:786)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
Corresponding part of my code:
AdjustConfig config = new AdjustConfig(this, someString, otherString);
When I turn off Proguard with minifyEnabled false; in my build.gradle, the error is gone.
My proguard-rules.pro looks like this:
-keepattributes **
-keep class !android.support.v7.internal.view.menu.**,** {*;}
-dontpreverify
-dontoptimize
-dontshrink
-dontwarn **
These Proguard rules might look a bit strange because they do but one thing: obfuscate classes in the android.support.v7.internal.view.menu package.
This procedure is a workaround for a a known issue of the Android Support library on Samsung devices.
Even more confusingly, the NoClassDefFoundError only occurs only devices running Android < 5.0.
Any ideas on what the reason could be or how to fix this?

The documentation says:
If you are using Proguard, add these lines to your Proguard file:
-keep class com.adjust.sdk.** { *; }
-keep class com.google.android.gms.common.** { *; }
-keep class com.google.android.gms.ads.identifier.** { *; }

Related

okhttp3 minifyEnabled causes crash on Android 4.1.2

This code in okhttp:3.12.13 works fine with minifyEnabled false
private static boolean supportsAlpn() {
if (Security.getProvider("GMSCore_OpenSSL") != null) {
return true;
} else {
try {
Class.forName("android.net.Network"); //NoClassDefFoundError here if minifyEnabled true
return true;
} catch (ClassNotFoundException ignored) { }
}
return false;
}
but with minifyEnabled true the following error occurs on Android 4.1.2
Caused by: java.lang.ExceptionInInitializerError
at okhttp3.OkHttpClient.newSslSocketFactory(OkHttpClient.java:292)
at okhttp3.OkHttpClient.<init>(OkHttpClient.java:258)
at okhttp3.OkHttpClient.<init>(OkHttpClient.java:231)
Caused by: java.lang.ExceptionInInitializerError
at java.lang.Class.classForName(Native Method)
at java.lang.Class.forName(Class.java:217)
at java.lang.Class.forName(Class.java:172)
at okhttp3.internal.platform.AndroidPlatform.supportsAlpn(AndroidPlatform.java:219)
at okhttp3.internal.platform.AndroidPlatform.buildIfSupported(AndroidPlatform.java:262)
at okhttp3.internal.platform.Platform.findAndroidPlatform(Platform.java:246)
at okhttp3.internal.platform.Platform.findPlatform(Platform.java:202)
at okhttp3.internal.platform.Platform.<clinit>(Platform.java:78)
Caused by: java.lang.NoClassDefFoundError
at android.net.Network.<clinit>(Unknown Source)
What lines should be added to Proguard to avoid the crash?
Edit:
Adding rules 1 and 2 didn't help.
These rules worked, but apk size gets increased by 0.6 MB.
-keepattributes Signature
-keepattributes *Annotation*
-keep class okhttp3.** { *; }
-keep interface okhttp3.** { *; }
-dontwarn okhttp3.**
I'm wondering if it is possible to fix the issue without keeping all okhttp3 classes in the apk.
Just get rules from below files/links
https://raw.githubusercontent.com/square/okhttp/master/okhttp/src/jvmMain/resources/META-INF/proguard/okhttp3.pro
https://github.com/square/okio/blob/master/okio/src/jvmMain/resources/META-INF/proguard/okio.pro
Refer
https://square.github.io/okhttp/features/r8_proguard/
I experienced an identical problem on Android 4.1.1 with OkHttp 3.12.12 but the suggest fix to proguard rules did not correct my issue.
Interesting to note that the NoClassDefFoundError appears to be coming from a copy of android.net.Network that is bundled in the APK by r8 but contains the following unusual code (disassembled with apktool):
.class public synthetic Landroid/net/Network;
.super Ljava/lang/Object;
# interfaces
.implements Landroid/os/Parcelable;
# direct methods
.method static synthetic constructor <clinit>()V
.locals 1
new-instance v0, Ljava/lang/NoClassDefFoundError;
invoke-direct {v0}, Ljava/lang/NoClassDefFoundError;-><init>()V
throw v0
.end method
This is why the NoClassDefFoundError has no message and originates from clinit (static initializer).
This is a fairly wild guess but perhaps r8 generates this code internally for the minify phase and then accidentally materializes it into the APK? So it appears this is likely some kind of bug in r8.
Regardless the fix that actually worked was to not use Android Gradle plugin 7.3.X and instead revert to AGP 7.2.2. AGP 7.4.0-beta04 also appears to work. With these other version of AGP the unsual android.net.Network class does not appear in the APK.

How to make org.apache.http.legacy work with ProGuard (azure mobile services)?

The problem:
I'm using android mobile services, which relies on androidhttpclient.
Referencing org.apache.http.legacy resolves all the problems and the app runs just fine. However, with proguard on, I keep running into issues.
The problem plays out in two scenarios. If I keep the export checkbox checked (in jave build path), I get a 'Stub!' exception as expected (see discussion below)(see screenshot for which checkbox I'm talking about)
The runtime crash of type: "Stub!":
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.stuffd/com.stuffd.MainActivity}: java.lang.RuntimeException: Stub!
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2345)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2405)
at android.app.ActivityThread.access$800(ActivityThread.java:149)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1324)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:211)
at android.app.ActivityThread.main(ActivityThread.java:5317)
at java.lang.reflect.Method.invoke(Method.java)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1016)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:811)
Caused by: java.lang.RuntimeException: Stub!
at org.apache.http.message.AbstractHttpMessage.(AbstractHttpMessage.java:7)
at org.apache.http.client.methods.HttpRequestBase.(HttpRequestBase.java:7)
at org.apache.http.client.methods.HttpGet.(HttpGet.java:8)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceJsonTable.executeGetRecords(MobileServiceJsonTable.java:952)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceJsonTable.executeUrlQuery(MobileServiceJsonTable.java:183)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceJsonTable.execute(MobileServiceJsonTable.java:160)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceTable.execute(MobileServiceTable.java:158)
at com.microsoft.windowsazure.mobileservices.table.MobileServiceTable.execute(MobileServiceTable.java:249)
at com.microsoft.windowsazure.mobileservices.table.query.ExecutableQuery.execute(ExecutableQuery.java:101)
If however, I keep the checkbox unchecked (as suggested - see discussion below), I get and AbstractMethodError exception.
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:300)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:811)
Caused by: java.lang.AbstractMethodError: abstract method "java.lang.String org.apache.http.client.methods.HttpRequestBase.getMethod()"
at android.net.http.AndroidHttpClient.getMethod(AndroidHttpClient.java:283)
at android.net.http.AndroidHttpClient.execute(AndroidHttpClient.java:301)
proguard config used:
-dontwarn org.apache.http.**
-dontwarn android.net.http.**
-dontwarn com.microsoft.windowsazure.mobileservices.**
Has anyone else run into this and has figured it out?
Here's what I am using, allowing the OS to properly replace the stubbed methods at runtime.
-keep class org.apache.http.** { *; }
-keep class org.apache.commons.codec.** { *; }
-keep class org.apache.commons.logging.** { *; }
-keep class android.net.compatibility.** { *; }
-keep class android.net.http.** { *; }
-dontwarn org.apache.http.**
-dontwarn android.webkit.**
It's all the stubbed packages provided by org.apache.http.legacy.jar.
You're right not exporting the legacy apache lib. However it has to be located outside the libs folder and added to the Build Path (when using Eclipse). Otherwise it gets exported anyway with your Android Private Libraries.
I'm using GMS, Volley and AndroidHttpClient in my own communication classes.
Here's what I had to add to the proguard settings:
-dontwarn org.apache.http.**
-dontwarn com.google.android.gms.**
-dontwarn com.android.volley.toolbox.**
-dontwarn com.myapp.communication.**
-keep class com.google.android.gms.** { *; }

Genson with Android - Proguard config

I have a problem with proguard config in Android Project.
I'm using Genson to parse incoming JSON data.
It is fast and there is no need for extra configuration or deserializers, because on the Server-side there is also Genson.
Everything works fine in debug mode, but in release, with proguard it doesn't.
Unfortunately I have some error during runtime:
FATAL EXCEPTION: main
Process: com.es.mobile.meedy, PID: 16650
java.lang.UnsupportedOperationException: Couldn't find parameter at 0 from type interface com.owlike.genson.Converter , you should first locate the parameterized type, expand it and then use typeOf.
at com.owlike.genson.reflect.TypeUtil.typeOf(Unknown Source)
at com.owlike.genson.GensonBuilder.withConverters(Unknown Source)
at com.mypackage.f.k.a(Unknown Source)
at com.a.a.b.n.a(Unknown Source)
at com.a.a.i.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
It happens even if datamodel is in keep class. I tried all configrations with keep class, classmembers, etc. What else can i do?
EDIT
What else do I know:
I tried keep class with all classes in my project.
I have keep class with genson (-keep class com.owlike.genson.** { *; })
Instanceof with my class shows that it is instance of com.owlike.genson.Converter
The solution to the problem was to add -keepattributes Signature
If annotations are being used then this option should be enabled too -keepattributes *Annotation*
Also the application class being ser/de by Genson must also be provided:
-keep class com.mypackage.model.** { *; }
-keep class com.owlike.genson.*{ *; }
Add that line to your ProGuard configuration.
-keep [,modifier,...] class_specification
Specifies classes and class members (fields and methods) to be preserved as entry points to your
code. For example, in order to keep an application, you can specify
the main class along with its main method. In order to process a
library, you should specify all publicly accessible elements.

Getting Facebook com.facebook.FacebookGraphObjectException: Factory can't proxy method error

I am getting this exception. Please find below the complete stack trace.
com.facebook.FacebookGraphObjectException: Factory can't proxy method: public abstract java.lang.String com.junobe.android.junowallet.SNS.u.a()
at com.facebook.model.GraphObject$Factory.verifyCanProxyClass(SourceFile:290)
at com.facebook.model.GraphObject$Factory.createGraphObjectProxy(SourceFile:216)
at com.facebook.model.GraphObject$Factory.access$0(SourceFile:215)
at com.facebook.model.GraphObject$Factory$GraphObjectProxy.proxyGraphObjectMethods(SourceFile:583)
at com.facebook.model.GraphObject$Factory$GraphObjectProxy.invoke(SourceFile:521)
at $Proxy0.cast()
at com.facebook.Response.getGraphObjectAs(SourceFile:124)
at com.junobe.android.junowallet.SNS.FacebookOpenGraphController.handleResponse(SourceFile:568)
at com.junobe.android.junowallet.SNS.FacebookOpenGraphController.access$6(SourceFile:555)
at com.junobe.android.junowallet.SNS.FacebookOpenGraphController$3.onPostExecute(SourceFile:522)
at com.junobe.android.junowallet.SNS.FacebookOpenGraphController$3.onPostExecute(SourceFile:1)
at android.os.AsyncTask.finish(AsyncTask.java:417)
at android.os.AsyncTask.access$300(AsyncTask.java:127)
at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:429)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:130)
at android.app.ActivityThread.main(ActivityThread.java:3685)
at java.lang.reflect.Method.invokeNative(Method.java)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
at dalvik.system.NativeStart.main(NativeStart.java)
I am not getting this issue on all devices or all times. Identified this from crashlytics.
I have a hunch that it may be some proguard - obfuscation issue on Android.
I have added the following lines to in the proguard file (As per facebook Documentation):
-keep class com.facebook.** { *; }
-keepattributes Signature
Is there something I am missing .. Any assistance or solution would be welcome.
The only thing that I found that worked for me was to not obfuscate classes that extended facebook classes. I had a bunch of files in one package so for all those files I just excluded them by adding this to my proguard-project.txt.
-keep class com.classes.extending.facebook.** { *; }

java.lang.NoClassDefFoundError: org.apache.http.params.SyncBasicHttpParams

When i debug my app it is working fine but when i try to export my apk and install it i am getting this issue:
java.lang.NoClassDefFoundError: org.apache.http.params.SyncBasicHttpParams
at aig.a(Unknown Source)
at ahy.q(Unknown Source)
at ahy.d(Unknown Source)
at ahy.r(Unknown Source)
at ahy.c(Unknown Source)
at ahy.a(Unknown Source)
at ahy.a(Unknown Source)
at ahy.execute(Unknown Source)
at com.application.Login.a(Unknown Source)
at com.application.Login.onCreate(Unknown Source)
at android.app.Activity.performCreate(Activity.java:5115)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1083)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2248)
at android.app.ActivityThread.access$600(ActivityThread.java:145)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1246)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5095)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:898)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:665)
at dalvik.system.NativeStart.main(Native Method)
I am using proguard,
I have added reference libs also like this:
-libraryjars /libs/org.apache.httpcomponents.httpclient_4.2.1.jar
-libraryjars /libs/signpost-commonshttp4-1.2.1.1.jar
-libraryjars /libs/signpost-core-1.2.1.1.jar
-libraryjars /libs/signpost-jetty6-1.2.1.1.jar
-libraryjars /libs/twitter4j-core-2.1.6.jar
any idea..#thanks
There is no HttpCore in your libs.
Please import HttpCore
This link is HttpCore 4.1, You can search HttpCore 4.2 or 4.3 if you want.
In the future, when you import a library please ensure that you import the relevant library
Add the following lines to you proguard-project.txt file:
-keep class org.apache.http.** {
*;
}
I would also suggest you to use repackaged version of HttpClient for Android instead of original HttpClient jar to avoid class loading collisions with the version bundled with Android. But as far as I can see you'll also need to rebuild Signpost HttpClient module to use ch.boye.httpclientandroidlib package instead of org.apache.http (and don't forget to update package name in proguard-project.txt as well).
Import the package on your bundle
Import-Package: org.apache.http.params
In the standard Android builds (Ant, Eclipse, Gradle), don't specify -libraryjars or -injars, since the build scripts will already specify those for you. Just make sure you add all necessary library jars to the libs directory, as usual, so the build scripts will include them.
In Eclipse, libraries may need to be marked as Exported.

Categories

Resources