Proguard keeps string constants used for logging - android

Following Removing unused strings during ProGuard optimisation I created Logg class that is designed to be easily removed by Proguard:
public class Logg {
public static void e(Object... args) {
Log.e(TAG, buildString(args));
}
public static void d(Object... args) {
Log.d(TAG, buildString(args));
}
}
Next, I added these rules to proguard-rules.pro used by project:
-assumenosideeffects class com.mypackage.Logg {
public static *** d(...);
public static *** e(...);
}
-optimizationpasses 10
After the project is built, I inspect the resulting classes.jar file with JD-GUI and see lines like these:
new Object[1][0] = "Some log message";
The Logg.e(... call is removed but the constant is still there. With -optimizationpasses 5 the line was mentioning String instead of Object.
Is there a way to make sure that Proguard will remove those Strings?

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.

How to Obfuscated Jar or AAR files

Can someone help me about, obfuscated or give me example to do this?
I created an .aar file and .jar file and put the class of getter and setter that will give value if they access on it.
but the thing in need to put the hidden values that someone will not see what is the value on it.
package com.example.test;
public class MyClass extends privateClass{
String testing;
public MyClass() {
this.testing = getStringExample();
}
public String getTesting() {
return testing;
}
public void setTesting(String testing) {
this.testing = testing;
}
}
and this class must be hide/obfuscated to the other developers if i give my library
package com.example.test;
public class privateClass {
String getStringExample()
{
return "TEST RESULT";
}
}
Note: I tried to put proguard too, and check the library but still they can see my private class, , i tried to use interface and extends the class but still the same,
here is my proguard example:
-optimizationpasses 5
-dontusemixedcaseclassnames
-dontskipnonpubliclibraryclasses
-dontwarn ccom.example.test.R*
-verbose
-optimizations !code/simplification/arithmetic,!field/*,!class
-keepclassmembers class com.example.test.** { *; }
-keep class com.example.eyefixdata.** {
void set*(***);
void set*(int, ***);
boolean is*();
boolean is*(int);
*** get*();
*** get*(int);
}
Please save my day. hope you help me.
Thanks in advance.
You can move your private classes/interfaces to other packages, e.g. put your privateClass to an internal package package com.example.your.library.internal; to distinguish with your public classes/interfaces.
package com.example.your.library.internal;
public class privateClass {
String getStringExample()
{
return "TEST RESULT";
}
}
And add below line to your proguard configuration
-keep public class com.example.your.library.* { public *; }
Note that you should use single wild char * to NOT obfuscate the internal packages.

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.

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.

Remove LibGDX logs in Android using ProGuard

I have a proguard.cfg file which contains several statements including optimization passes and logs suppression as :
-assumenosideeffects class android.util.Log { *; }
-assumenosideeffects class com.badlogic.gdx.Application {
public static void debug(...);
public static void error(...);
public static void log(...);
}
Calls to Log.* are correctly removed in the final output APK file. But gdx log calls are still in the code. For example I can still see things like that in the output :
Gdx.app.debug("debug()", "^");
Gdx.app.error("error()", "^");
Gdx.app.log("log()", "^");
I also tried to put this part of my config in a proguard-optimize.txt file as I have seen on similar questions and then setting the proper value in project.properties files like this : proguard.config=proguard-optimize.txt:proguard.txt but it doesn't work !
These calls get removed only if I put a general wildcard :
-assumenosideeffects class com.badlogic.gdx.Application {
*;
}
But I don't want to remove calls to other Application's static methods, like add* and get*() ones.
Optimization step is enabled (6 passes).
Gdx.app.debug is not static its an instance method (app is a static field of the Gdx class).
Try:
-assumenosideeffects class com.badlogic.gdx.Application {
public void debug(...);
public void error(...);
public void log(...);
}
Try something like this in your application's code:
Gdx.app.setLogLevel(Application.LOG_NONE);
That will prevent messages from being logged.
Cheers!

Categories

Resources