I've been struggling with this one for a while now. I'm trying to Generate Signed APK in IntelliJ IDEA 13.1.3 and Run ProGuard 4.7 on the APK but I can't get rid of the following error:
Error: ProGuard: [project_name] Error: Can't read [C:\Program Files (x86)\Android\android-sdk\tools\proguard\libs] (No such file or directory)
The error message is preceded by this message:
Information: ProGuard: [project_name] Reading library directory [C:\Program Files (x86)\Android\android-sdk\tools\proguard\libs]
There is only a lib directory in that location containing proguard.jar and the two other jar files. I created an empty libs directory but got even more errors after that.
Otherwise the obfuscation seems to work properly, and without the obfuscation the signed APK is generated correctly.
The Android SDK Build-tools version is 20.
This is the proguard-project file:
-libraryjars libs
-keep class android.support.v4.app.** { *; }
-keep interface android.support.v4.app.** { *; }
-keep class * extends java.util.ListResourceBundle
{
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable
{
public static final *** NULL;
}
-keepnames #com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class *
{
#com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable
{
public static final ** CREATOR;
}
UPDATE
It seems that this problem boils down to the line -libraryjars libs in the proguard-project file. I managed to properly Generate Signed APK with a simple test project when I removed that line from proguard-project.txt. However, when -libraryjars libs wasn't removed, the obfuscation failed.
If that line is stripped when trying to run ProGuard on the actual project, it gives even more errors.
Thanks for your answer, Eric.
Actually, I already solved the problem. Just hadn't updated the answer here until now.
Yes, -libraryjars in proguard-project.txt was the root of all evil. I just included it there because of some example configurations I came across.
Here's the properly working configuration:
-keep class * extends java.util.ListResourceBundle
{
protected Object[][] getContents();
}
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable
{
public static final *** NULL;
}
-keepnames #com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class *
{
#com.google.android.gms.common.annotation.KeepName *;
}
-keepnames class * implements android.os.Parcelable
{
public static final ** CREATOR;
}
-keep public class com.google.android.gms.ads.**
{
public *;
}
-keep public class com.google.ads.**
{
public *;
}
-keep class com.android.vending.billing.**
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-dontwarn com.google.android.gms.**
You should have -libraryjars or -injars in your configuration. The Android build process (Ant, Eclipse, Gradle, and presumably IntelliJ IDEA as well) internally already specifies those options for you.
I haven't come across the Android SDK adding -libraryjars to proguard-project.txt (and specified paths are relative to the directory of the configuration file itself, not to .../tools/proguard), but maybe you should update to the latest version of the SDK to avoid the problem.
Related
I am trying to add custom Proguard rules for my app, but I am not sure into which file I should add those custom rules. I know of three files
1)Android/sdk/tools/proguard/proguard-android.txt
2)Android/sdk/tools/proguard/proguard-project.txt
3)Project --> app --> proguard-rules.pro
First of all you will use the
3)Project --> app --> proguard-rules.pro
and
few generic custom rules which are safe to apply on app and wouldn't
hinder the functioning of it
depends on the code in your app but if you will set minifyEnabled to true(which is recommended) this could lead to a lot of issues which can be solved through proguard rules file.
This is my proguard file for one of my projects where I'm using Fabric, httpApacheClient, shareActionProvider and some other libraries that needs specific rules for proguard.
# This will ignore warnings for missing translations and some other wanrinings
-ignorewarnings
# Keeping line numbers for easy error tracking :
-keepattributes SourceFile,LineNumberTable
# Support ShareActionProvider will not work without this line :
-keep class android.support.v7.widget.ShareActionProvider { *; }
# Flurry Crashlytics
-keep class com.flurry.** { *; }
-dontwarn com.flurry.**
-keepattributes *Annotation*,EnclosingMethod
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int); }
# Preserve Flurry mediation classes for DFP/AdMob Ads keep public class com.google.ads.mediation.flurry.**
# Google Play Services library
-keep class * extends java.util.ListResourceBundle {
protected Object[][] getContents(); }
-keep public class com.google.android.gms.common.internal.safeparcel.SafeParcelable {
public static final *** NULL; }
-keepnames #com.google.android.gms.common.annotation.KeepName class *
-keepclassmembernames class * {
#com.google.android.gms.common.annotation.KeepName *; }
-keepnames class * implements android.os.Parcelable { public static final ** CREATOR;
}
-keepattributes InnerClasses, EnclosingMethod
-keep class com.ironsource.mobilcore.**{ *; }
-dontwarn org.apache.http.**
-dontwarn android.net.http.AndroidHttpClient
-dontwarn android.app.Notification
-keep class com.dianxinos.DXStatService.stat.TokenManager {
public static java.lang.String getToken(android.content.Context);
}
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.app.Activity
-keep public class * extends android.content.ContentProvider
And almost you will find related proguard settings in the documentation of any external library you use.
in
3)Project --> app --> proguard-rules.pro
There are not generic proguard rules. All those generic ones already included with SDK, It depends on what features and libraries are you using in your project. Also there is no safeway of doing it. You have to apply rules and test app -> fix any issues then repeat same process.
I'm trying to configure Proguard, but I can't manage to get it working.
This is the error:
I've tried things like:
-keep class com.android.auth.TwitterHandle.** { *; }
-keep class oauth.** { *; }
Without any luck.
Anyways, I don't really think ignoring is the answer. Because that might mean something is broken.
Any tips?
Thanks!
The warnings indicate that the AndroidQuery library depends on the OAuth library. Apparently, you're using the former library in your project, but the latter library is missing. You could add the missing library, but if your application is working fine without it in debug mode, you can just tell ProGuard to ignore the missing dependency. In this case:
-dontwarn com.androidquery.auth.**
or, to the same effect:
-dontwarn oauth.signpost.**
See the ProGuard manual > Troubleshooting > Warning: can't find referenced class
(I am the developer of ProGuard)
Add these lines to your proguard file.
-dontwarn oauth.**
-dontwarn com.android.auth.TwitterHandle.**
-keep class oauth.** { *; }
-keep class com.android.auth.TwitterHandle.** { *; }
Edit:
Anyways, I don't really think ignoring is the answer. Because that
might mean something is broken.
If you want to use Proguard and you are having some errors such as class not found, then you must disable/ignore their obfuscation. Because Proguard renames names, fields and methods of classes while obfuscating. This becomes a big problem if reflection is used for that classes. So you have to say proguard to ignore(not obfuscate) some classes to prevent this problem.
Please try this post https://stackoverflow.com/a/15477898/1665964
Insert to skip obfuscated in ProGuard your libs, jars, Classes and Subclasses with this example
-optimizationpasses 5
-dump class_files.txt
-printseeds seeds.txt
-printusage unused.txt
-printmapping mapping.txt
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-allowaccessmodification
-repackageclasses ''
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.MapActivity
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-libraryjars libs/commons-io-2.2.jar
-libraryjars libs/gson-2.2.2.jar
-keep public class org.apache.commons.io.**
-keep public class com.google.gson.**
-keep public class com.google.gson.** {public private protected *;}
##---------------Begin: proguard configuration for Gson ----------
-keepattributes Signature
-keepattributes *Annotation*
-keep class com.mypackage.ActivityMonitor.ClassMultiPoints.** { *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints { public protected *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints$ClassPoints { public protected *; }
-keep public class com.mypackage.ActivityMonitor$ClassMultiPoints$ClassPoints$ClassPoint { public protected *; }
##---------------End: proguard configuration for Gson ----------
The reason for error must be that you might be using an external jar file (in libs folder).
If this is the case, adding the following line before -keep class ... lines should solve your problem.
-libraryjars libs/<jar_filename>
If u are unfamiliar with proguard cmd tool then you can try proguard gui located at tools/proguard/lib/proguardgui of your android SDK folder.
open proguardgui and load your configuration file.
then in Input / output section add your input and output jar as well as add your android lib used in your project.
***** your main problem is that you havent added your library (Aquery.jar and others) jar that is used in your project , so that proguard can't find the required Classes.***
Application crashes after proguard (proguard generated by eclipse IDE).
logcat stacktrace
W/SupportMenuInflater(13657): Cannot instantiate class: android.support.v7.widget.ShareActionProvider
W/SupportMenuInflater(13657): java.lang.ClassNotFoundException: android.support.v7.widget.ShareActionProvider
W/SupportMenuInflater(13657): at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:61)
E/AndroidRuntime(13657): FATAL EXCEPTION: main
E/AndroidRuntime(13657): java.lang.NullPointerException
E/AndroidRuntime(13657): at com.mypack.app.MainActivity.onCreateOptionsMenu(Unknown Source)
E/AndroidRuntime(13657): at android.app.Activity.onCreatePanelMenu(Activity.java:2571)`
default version of proguard.cfg file
# This is a configuration file for ProGuard.
# http://proguard.sourceforge.net/index.html#manual/usage.html
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
# Optimization is turned off by default. Dex does not like code run
# through the ProGuard optimize and preverify steps (and performs some
# of these optimizations on its own).
-dontoptimize
-dontpreverify
# Note that if you want to enable optimization, you cannot just
# include optimization flags in your own project configuration file;
# instead you will need to point to the
# "proguard-android-optimize.txt" file instead of this one from your
# project.properties file.
-keepattributes *Annotation*
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
#-keep public class android.support.v7.widget.ShareActionProvider
# For native methods, see http://proguard.sourceforge.net/manual/examples.html#native
-keepclasseswithmembernames class * {
native <methods>;
}
# keep setters in Views so that animations can still work.
# see http://proguard.sourceforge.net/manual/examples.html#beans
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
}
# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
# For enumeration classes, see http://proguard.sourceforge.net/manual/examples.html#enumerations
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
-dontwarn android.support.**
`
EDIT: to resolve the problem you need to add this lines to proguard.cfg and have no errors. New lines tells proguard to ignore android.support libraries.
-dontwarn android.support.v4.**
-keep class android.support.v4.** { *; }
-dontwarn android.support.v7.**
-keep class android.support.v7.** { *; }
In your proguard config, you have commented out the keep of the class that it can't find:
#-keep public class android.support.v7.widget.ShareActionProvider
Did you try uncommenting that and building again?
EDIT: since that didn't solve your problem, maybe try the catch all described here:
Android Proguard configuration for the v7 Support Library ActionBar
specifically, try adding:
-keep class android.support.v7.internal.** { *; }
-keep interface android.support.v7.internal.** { *; }
-keep class android.support.v7.** { *; }
-keep interface android.support.v7.** { *; }
You can then make it more specific if that works, because this obviously just keeps all the support library classes, even ones you don't use.
I am having an error with the Proguard file in Android.
The point is, I know how to use it in an Android Project, but now, I need to use it for an Android Library Project, and the .jar extracted (there is no resources on the library), to obfuscate the code, because I would like to distribute my library for everyone to use it, but with the code obfuscated.
My Android library project is a normal one, I just take the .jar with is contained in the "bin" folder from the Library Project, and I am trying to use the Proguard to obfuscate it this way:
java -jar proguard.jar #proguard-project -verbose
My Proguard file is the next one:
-injars in.jar
-outjars out.jar
-libraryjars /home/jorider/wul4/adt-android/sdk/platforms/android-17/android.jar
-libraryjars /home/jorider/wul4/adt-android/sdk/extras/android/support/v4/android-support-v4.jar
-libraryjars commons-codec-repackaged-3.1-b36.jar
-libraryjars httpmime-4.2.5.jar
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-verbose
-dontoptimize
-dontpreverify
-keepattributes Annotation
-keep public class com.google.vending.licensing.ILicensingService
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native ;
}
-keepclassmembers public class * extends android.view.View {
void set*(*);
get();
}
-keepclassmembers class * extends android.app.Activity {
public void *(android.view.View);
}
-keepclassmembers enum * {
public static *[] values();
public static * valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
-keepclassmembers class *.R$ {
public static ;
}
-dontwarn android.support.**
The result I get for running that on the console is :
Shrinking...
java.io.IOException: The output jar is empty. Did you specify the proper '-keep' options?
Anyone knows why?
Thanks a lot!
You can find a configuration for processing libraries in the ProGuard manual > Examples > A typical library.
Notably, you'll need to preserve all public API:
-keep public class * {
public protected *;
}
When I test my app on the device using Run as --> Android Application, Phonegap functionality works fine.
When I export a .apk file using Eclipse and run it on the device, Phonegap functionality is not working. I assume it's likely a Proguard issue. How do I solve this?
proguard-properties.txt
-keep public class * extends com.phonegap.api.Plugin
-keep public class * extends org.apache.cordova.api.Plugin
-keep public class org.apache.cordova.DroidGap
-keep public class org.apache.cordova.**
-libraryjars /path/to/adt-bundle-mac/sdk/tools/lib/commons-codec-1.4.jar
-dontwarn android.webkit.*
This worked:
-keep public class * extends com.phonegap.api.Plugin
-keep public class * extends org.apache.cordova.api.Plugin
-keep public class org.apache.cordova.DroidGap
-keep public class org.apache.cordova.**
-keep public class org.apache.**
-dontwarn android.webkit.*
-dontwarn org.apache.**
-keep public class * extends org.apache.cordova.api.CordovaPlugin
-keep class org.apache.cordova.** { *; }
(Phonegap 2.4 Android Proguard config)
I used :
-keep class org.apache.cordova.** { *; }
while proguarding my cordova application but it did not work. But when I wrote the same statement after '-keep' statements of all java files then it worked absolutely fine.(It might be because after keep of all cordova functions, keep of java functions overriding and excluding the cordova functions again).
But one of my project changing of order did not matter while in one it worked only after the order change i.e., by writing -keep class org.apache.cordova.** { *; } statement at the end in proguard config file.