How to tell ProGuard to keep everything in a particular package? - android

My application has many activities and uses native library too. With the default ProGuard configuration which Eclipse generates ProGuard removes many things - OnClick methods, static members, callback methods which my native library uses... Is it there a simple way to instruct ProGuard to NOT remove anything from my package? Removing things saves only about 2.5% of the application size, but breaks my application completely. Configuring, testing and maintaining it class by class in ProGuard configuration would be a pain.

EDIT This answer is 10 years old - it may not apply to newer proguard versions.
I think you need to add these flags at the very least (modify for you individual package names):
-keep class javax.** { *; }
-keep class org.** { *; }
-keep class twitter4j.** { *; }
Also, add these flags:
-dontshrink
-dontoptimize
-dontpreverify
Here's my whole config file: of my Proguard.cfg:
-dontshrink
-dontoptimize
-dontpreverify
-verbose
-dontwarn javax.management.**
-dontwarn java.lang.management.**
-dontwarn org.apache.log4j.**
-dontwarn org.apache.commons.logging.**
-dontwarn org.slf4j.**
-dontwarn org.json.**
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keep class javax.** { *; }
-keep class org.** { *; }
-keep class twitter4j.** { *; }
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}

As final result I found that just keeping all class members is not enough for the correct work of my application, nor necessary. I addded to the settings file this:
-keepclasseswithmembers class * {
void onClick*(...);
}
-keepclasseswithmembers class * {
*** *Callback(...);
}
The case with onClick* is for all methods which I address in android:onClick atribute in .xml layout files (I begin the names of all such methods with 'onClick').
The case with *Callback is for all callback methods which I call from my native code (through JNI). I place a suffix 'Callback' to the name of every such method.
Also I added few rows for some special cases with variables which I use from native code, like:
-keep class com.myapp.mypackage.SomeMyClass {
*** position;
}
(for a varible with name 'position' in a class with name 'SomeMyClass' from package com.myapp.mypackage)
All this is because these onClick, callback etc. must not only be present but also kept with their original names. The other things ProGuard can optimize freely.
The case with the native methods is important also, but for it there was a declaration in the generated from Eclipse file:
-keepclasseswithmembernames class * {
native <methods>;
}

I know this is an old question but I hope that the following information might help other people.
You can prevent ProGuard from removing anything in a certain package as follows;
-keep,allowoptimization,allowobfuscation class com.example.mypackage.** { *; }
Using the modifiers allowoptimization and allowobfuscation will make sure that ProGuard still obfuscates and optimizes the code. Shrinking will of course be disabled as intended.
You can easily verify how these -keep rules affect the code without the need to (re-)build using the ProGuard Playground.

Related

Why proguard don´t know automatically which files should be kept

Why android studio can´t infer which classes do we need so the other´s can be removed using shrink?
Why do we need to write manually which classes should be kept?
ProGuard is a general-purpose Java development tool. It knows nothing about classes that might be referred to from the Android manifest, layout resources, menu resources, preference XML, and so on.
More generally, ProGuard has no way of reliably determining what classes are loaded via reflection, which is how all of the above is implemented. For those classes, you need to teach ProGuard to keep them.
Also the "update project" command from /ANDROID_SDK/tools/android will generate a proguard with common classes that should be kept.
The default is enough for most applications.
You should add Innerclasses that are used as listener of JavaScript on WebViews.
And the cases you find that you will need names (reflections or anything else)
The default proguard.cfg looks like this:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-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 *;
}

Setting up Proguard with a Library project that depends on external jars

My android project has many dependencies, one of them has a libs folder with some jars, and everything is working fine until i try using proguard.
When running proguard i got an error with this log:
Warning: [!!few lines like this!!]: can't find superclass or interface [...]
Warning: [!!many lines like this!!]: can't find referenced class [...]
You should check if you need to specify additional program jars.
Warning: there were 190 unresolved references to classes or interfaces.
You may need to specify additional library jars (using '-libraryjars').
Warning: there were 6 unresolved references to program class members.
Your input classes appear to be inconsistent.
You may need to recompile them and try again.
Alternatively, you may have to specify the option
'-dontskipnonpubliclibraryclassmembers'.
java.io.IOException: Please correct the above warnings first.
then i tried to add the -libraryjars flag in my proguard config file, resulting in this additional warning, above the others:
Note: there were 698 duplicate class definitions.
The library project i cannot proguard is ShowcaseView (com.espian.showcaseview).
The jars in its library's libs folder are:
android-support-v4.jar
mockito-all-1.9.5.jar
nineoldandroids-2.4.0.jar
What should i do?!
EDIT
here's my proguard.cfg
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontskipnonpubliclibraryclassmembers
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
#-libraryjars ../ShowcaseView-master/library/libs/android-support-v4.jar
#-libraryjars ../ShowcaseView-master/library/libs/mockito-all-1.9.5.jar
#-libraryjars ../ShowcaseView-master/library/libs/nineoldandroids-2.4.0.jar
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** i(...);
public static *** w(...);
}
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-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 *;
}
#this is a try for all assets and res/raw/*html!
-keepclassmembers class **.R$* {
public static <fields>;
}
-keep class **.R$*
#ACRA specifics
# Restore some Source file names and restore approximate line numbers in the stack traces,
# otherwise the stack traces are pretty useless
-keepattributes SourceFile,LineNumberTable
# ACRA needs "annotations" so add this...
# Note: This may already be defined in the default "proguard-android-optimize.txt"
# file in the SDK. If it is, then you don't need to duplicate it. See your
# "project.properties" file to get the path to the default "proguard-android-optimize.txt".
-keepattributes *Annotation*
# keep this class so that logging will show 'ACRA' and not a obfuscated name like 'a'.
# Note: if you are removing log messages elsewhere in this file then this isn't necessary
-keep class org.acra.ACRA {
*;
}
# keep this around for some enums that ACRA needs
-keep class org.acra.ReportingInteractionMode {
*;
}
-keepnames class org.acra.sender.HttpSender$** {
*;
}
-keepnames class org.acra.ReportField {
*;
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public void addCustomData(java.lang.String,java.lang.String);
public void putCustomData(java.lang.String,java.lang.String);
public void removeCustomData(java.lang.String);
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public void handleSilentException(java.lang.Throwable);
}
Try this
-libraryjars /libs/mail.jar
-libraryjars /libs/activation.jar
-libraryjars /libs/additionnal.jar
Write your jar file path into the progurd.cfg or proguard-project.txt
You should add these lines for your libraries. They will don't warn for can't find reference class
-keep class com.nineoldandroids.** { *; }
-dontwarn -com.nineoldandroids.**

Ant seems to ignore jar generated by Proguard while packaging apk

I have a Jenkins build server for building Android APKs with ant and Android (SDK Revision 18). Releasing APKs is working fine. However if i enable proguard by providing a proguard.cfg and pointing to it by "proguard.config=proguard.cfg" in the project.properties the following seems to happen:
Proguard is executed (as seen from shell output and the existence of mappings.txt and seeds.txt afterwards)
an apk is generated. However the Stacktraces generated by the APK are not obfuscated at all.
Anybody got an idee on this? It seems that the jar generated by proguard is for some reasons not included in the apk.
Here is my Proguard Config
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/,!class/merging/
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-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 *;
}
#ACRA specifics
# we need line numbers in our stack traces otherwise they are pretty useless
-renamesourcefileattribute SourceFile
-keepattributes SourceFile,LineNumberTable
# ACRA needs "annotations" so add this...
-keepattributes *Annotation*
# keep this class so that logging will show 'ACRA' and not a obfuscated name like 'a'.
# Note: if you are removing log messages elsewhere in this file then this isn't necessary
-keep class org.acra.ACRA {
*;
}
# keep this around for some enums that ACRA needs
-keep class org.acra.ReportingInteractionMode {
*;
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public void addCustomData(java.lang.String,java.lang.String);
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter
{
public org.acra.ErrorReporter$ReportsSenderWorker handleSilentException(java.lang.Throwable);
}
The mappings.txt states that my code is obfuscated:
de.cellular.crashtest.ObfuscateThisClass -> de.cellular.crashtest.b:
However it is not obfuscated in the reported Stacktrace
It seems it was just a jenkins configuration problem: the apk was archived from the bin/ directory but the obfuscated one was in release/

Getting java.lang ExceptionInInitializerError when initializing ACRA

I integrated ACRA to my application to get crash reports from my app in beta stadium so I'm able to fix bugs, find errors in code, etc. If I run this on the emulator everything works fine and ACRA is up and running, but if I export a signed package of my application with Android Tools I get an ExceptionInInitializeError and the application is force closed on the device. If I catch this Error and proceed without ACRA the app itself runs like a charm...
has anybody here got the same issue with ACRA? could it be that it has something to do with ProGuard? I followed the ProGuard how to on ACRA homepage but perhaps I'm missing something on this?
here's what my proguard.cfg looks like:
-injars 'C:\Workspaces\motodevWs\gp2012\bin\classes'
-injars 'C:\Workspaces\motodevWs\gp2012\libs'
-outjars 'C:\Workspaces\motodevWs\gp2012\bin\classes-processed.jar'
-libraryjars 'C:\android\android-sdk\platforms\android-7\android.jar'
-libraryjars 'C:\android\android-sdk\add-ons\addon_google_apis_google_inc_7 \libs\maps.jar'
-optimizations !code/simplification/arithmetic
-allowaccessmodification
-repackageclasses ''
-keepattributes *Annotation*,SourceFile,LineNumberTable,*Annotation*
-renamesourcefileattribute SourceFile
-dontpreverify
-dontwarn java.awt.**,javax.security.**,java.beans.**,com.sun.**
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.view.View {
public <init>(android.content.Context);
public <init>(android.content.Context,android.util.AttributeSet);
public <init>(android.content.Context,android.util.AttributeSet,int);
public void set*(...);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context,android.util.AttributeSet);
}
-keepclasseswithmembers class * {
public <init>(android.content.Context,android.util.AttributeSet,int);
}
-keepclassmembers class * extends android.os.Parcelable {
static android.os.Parcelable$Creator CREATOR;
}
-keepclassmembers class **.R$* {
public static <fields>;
}
# keep this class so that logging will show 'ACRA' and not a obfuscated name like 'a'.
# Note: if you are removing log messages elsewhere in this file then this isn't necessary
-keep class org.acra.ACRA {
<fields>;
<methods>;
}
# keep this around for some enums that ACRA needs
-keep class org.acra.ReportingInteractionMode {
<fields>;
<methods>;
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter {
public void addCustomData(java.lang.String,java.lang.String);
}
# keep this otherwise it is removed by ProGuard
-keep public class org.acra.ErrorReporter {
public org.acra.ErrorReporter$ReportsSenderWorker handleSilentException(java.lang.Throwable);
}
PROBLEM SOLVED!
After some effort on research and rethinking my problem I found the solution to the problem and it was indeed in my proguard.cfg file where I missed something!
somehow I managed not to keep enums, now I added
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
to my proguard.cfg and everything is working perfectly!!
So, to close this question with the answer I found myself, here is what I did to resolve this particular problem :) (taken from my question post):
After some effort on research and rethinking my problem I found the solution to the problem and it was indeed in my proguard.cfg file where I missed something!
somehow I managed not to keep enums, now I added
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
to my proguard.cfg and everything is working perfectly!!
THere is now a wiki concerning using ACRA with ProGuard
https://github.com/ACRA/acra/wiki/Proguard

Proguard Android App for LVL and Fragment Compatibility Support

I'm trying to use Proguard against my app which will eventually incorporate LVL and In-app Billing. The problem I have is that Proguard keeps crashing my app on start and it's hard to figure out what's failing.
I'm using the Android V4 support compatibility library and it seems to be blowing away that library as well as some other stuff.
Does anyone has a proguard.cfg that works with a basic version of the v4 compat library for starters?
Currently I'm using the stock proguard.cfg which doesn't work.
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontpreverify
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*
-keep public class * extends android.app.Activity
-keep public class * extends android.app.Application
-keep public class * extends android.app.Service
-keep public class * extends android.content.BroadcastReceiver
-keep public class * extends android.content.ContentProvider
-keep public class * extends android.app.backup.BackupAgentHelper
-keep public class * extends android.preference.Preference
-keep public class com.android.vending.licensing.ILicensingService
-keepclasseswithmembernames class * {
native <methods>;
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet);
}
-keepclasseswithmembernames class * {
public <init>(android.content.Context, android.util.AttributeSet, int);
}
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}
-keep class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator *;
}
That's not enough to produce a working application.. proguard will for example delete all your fragments by default, and there are some more compat. libraries it uses.
I've found the following works:
-dontwarn **CompatHoneycomb
-dontwarn **CompatHoneycombMR2
-dontwarn **CompatCreatorHoneycombMR2
-keep class android.support.v4.** { *; }
-keep public class * extends android.support.v4.**
-keep public class * extends android.app.Fragment
In theory if you simply want proguard as an obfuscator and are not ineterested in its other 'features', then
-dontshrink
-dontoptimize
Should switch it off. Even with that, though test thoroughly on a real android 1.6 phone. I didn't and found too late proguard had made a breaking change to the binary that only manifested on 1.6...
To have Proguard working with v4 compatibility library add this to your proguard.cfg:
-dontwarn **CompatHoneycomb
-keep class android.support.v4.** { *; }

Categories

Resources