Proguard/R8 exception to a keep rule - android

I am trying to remove logging using R8/Proguard, and I used
-assumenosideeffects class android.util.Log {
v(...);
d(...);
i(...);
w(...);
e(...);
}
which works fine. The issue arrised when trying to remove the custom logging in com.mypackage:
-assumenosideeffects class com.mypackage.MyCustomLogger {
v(...);
d(...);
i(...);
w(...);
e(...);
}
I have a rule that keeps all the public methods of the public classes from com.mypackage:
-keep, allowoptimization public class com.mypackage.** {
public *;
}
which I can't remove due to the scope of the project. This rule seemingly overrides the assumenosideeffects rule, and here is my question: how do I specify an exception to this keep rule? I know about the -if option but I haven't seen it anywhere used in the negative. I've tried writing -if class !com.mypackage.Logger before the -keep rule, but the build is taking a ridiculous amount of time and just never finishes.

I've found the answer, I need to add my Logger class within the keep rule like so:
-keep, allowoptimization public class !com.mypackage.MyCustomLogger, com.mypackage.** {
public *;
}

Related

How to strip logs with Timber.tag.(...).d(...) format using ProGuard?

I need to strip down all my Timber logs in my production build. I have added the following in my proguard-project.txt :
-assumenosideeffects class timber.log.Timber* {
public static *** tag(...);
public static *** v(...);
public static *** i(...);
public static *** w(...);
public static *** d(...);
public static *** e(...);
-assumenosideeffects class timber.log.Timber.tag* {*;}
}
However only logs with the format Timber.e() or Timber.i() etc is being stripped. Logs with Timber.tag(..).i(...) are not getting stripped.
Is there any way to achieve this? Thank you
wouldn't it be easier to do something line
if (BuildConfig.DEBUG) {
Timber.plant(Timber.DebugTree())
}
in your Application subclass? This way you will the logs only in debug
Stripping Timber.tag(...) cannot be done via Proguard. According to the usage guide,
In the optimization step, ProGuard can then remove calls to such methods, if it can determine that the return values aren't used.
Since Timber.tag(...) will return a Timber.Tree object, Proguard optimizer will not strip it off for you. Therefore, if you really want to strip off the log, you have to wrap it via a function e.g.
fun printDebugLog(tag: String, message: String) {
Timber.tag(tag).d(message)
}
Then you can use -assumenosideeffects to strip off printDebugLog call. Another thing you have to be aware of that when your class is in Kotlin, the following rules cannot be used to strip off Timber logs also
-assumenosideeffects class timber.log.Timber* {
public static *** d(...);
public static *** v(...);
public static *** i(...);
}
This is because when you decompile the Kotlin class to Java, logging will actually translated to
Timber.Forest.d(...)
Which will not be stripped off for the similar reason.

stream was reset: null

I had a strange bug which was hard to find :-(
In my Android app I use Retrofit2 with Moshi do access an api. I also use proguard-android-optimize.txt to make my app clean and small. And in my proguard-rules.pro I have:
-assumenosideeffects class timber.log.Timber { *; }
-assumenosideeffects class android.util.Log { *; }
With this combination I get this error stream was reset: null when I try to access the api.
To fix it I have to remove this assumenosideeffects lines from my proguard config. But why? Has anyone an idea why I get this network problem when proguard removes logging methods?
The wildcard * matches all methods, including methods in super classes, like Object#wait(). You don't really want to remove those invocations, so you should explicitly list the methods for which you want to remove the invocations:
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
ProGuard already prints out a warning if you specify the wildcard.

Dexguard security during debugging

i am using Dexguard in my android application to protect from
reverse engineering.Now in my application which is very big ,i have
used several places System.out.println in many classes in which i am
printing my server URL to debugg for my ease.Now when i am releasing
this application ,and this apk i am giving to other developers ,they
can see all the System.out.println things in their logcat. how
should i avoid that. This has serious issue.
First of all you shouldn't be using System.out.println directly everywhere. Use your own wrapper class for logging.
In dexguard/proguard you can use assumenosideeffects for removing codes that are unnecessary for release.
So for System.out.print you can add following in your dexguard rules.
-assumenosideeffects class java.io.PrintStream {
public void println(%);
public void println(**);
}
But this is risky as this class might be used for purposes other than logging.
Fastest way for you would be to use android.util.Log in place of System.out.print and then add following
-assumenosideeffects class android.util.Log {
public static boolean isLoggable(java.lang.String, int);
public static int v(...);
public static int i(...);
public static int w(...);
public static int d(...);
public static int e(...);
}
See proguard docs
good answer by #vKashyap, you might also want to add this as well...
-assumenosideeffects class java.lang.Exception {
public void printStackTrace();
}

Proguard - removing logs roboguice.util.Ln

In my app we are using logs from roboguice.util.Ln. I read how to remove logging by using proguard, but it seems to not working on roboguice logging. The last thing i tried was to add in my proguard configuration file something like this:
-assumenosideeffects class roboguice.util.Ln {
public static *** v(...);
public static *** i(...);
public static *** w(...);
public static *** d(...);
public static *** e(...);
public static boolean isDebugEnabled();
public static boolean isVerboseEnabled();
}
-assumenosideeffects class roboguice.util.Ln$Print {
public int println(int, java.lang.String);
protected java.lang.String processMessage(java.lang.String);
protected static java.lang.String getScope(int);
}
I also tried to do this without adding Print inner class, methods is***Enabled() etc. Any ideas how to remove roboguice.util.Ln logs?
Your configuration for roboguice.util.Ln looks correct. However, the option -assumenosideeffects only has effect with optimization enabled. In Android builds this means: in release mode and with the shared configuration proguard-android-optimize.txt in project.properties for Ant, or build.gradle for Gradle.

Android, Does Log reduces application speed?

In my application I have so many lines of logs, such as Log.i(), Log.e() and Log.d().
I use these logs widely through my application.
After I run my application if I connect device to Eclipse I can see hundreds of lines of log.
My question is does this behavior reduces application speed?
=============
Update
Thanks to Frank for his suggestion. I added proposed code into proguard.cfg then exported new APK file. It took so much time but finally new APK file generated. However, when I test it in a real device I still can see logs.
This is my proguard.cfg:
# 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
# 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.**
# Hesam - Remove all logs
-assumenosideeffects class android.util.Log {
public static int v(...);
public static int d(...);
public static int i(...);
public static int w(...);
public static int e(...);
}
#-libraryjars /libs/gcm.jar
#-libraryjars /libs/libGoogleAnalytics.jar
#-libraryjars /libs/twitter4j-core-android-2.2.6.jar
#-libraryjars /libs/universal-image-loader-1.5.4.jar
-dontwarn javax.management.**
-dontwarn java.lang.management.**
-dontwarn org.apache.**
-dontwarn org.slf4j.**
-dontwarn org.json.*
-keep class com.google.** { *; }
-keep class twitter4j.** { *; }
-keep class com.nostra13.** { *; }
The answer is obvious, YES it does.
But there is a solution, you can ask Proguard to remove log statements of any level that you desire. Like this your users are not impacted by the verbose logging that they don't see anyway..
Add folowing to your Proguard config:
-assumenosideeffects class android.util.Log {
public static *** d(...);
public static *** v(...);
public static *** i(...);
public static *** w(...);
public static *** e(...);
public static *** wtf(...);
}
This will remove LOG.d and LOG.v statements, you can expand as you like..

Categories

Resources