0

I was hoping for a way to comment out code on release versions.

What led me to Ant was that Proguard's way of removing Log.D (debug) calls was unsatisfactory as it was leaving the string literals in the dex files, even though the Log.D code was being removed by it's optimisation technique. As pointed out on this thread Removing unused strings during ProGuard optimisation

There someone one has suggested Ant could be used with a replace algorithm but this wipes out the code when it is run. I was hoping if there was a way of commenting out the code so it became //ant Log.d, then once it compiles the //ant could be removed.

I am new to ant, and I wasn't able to find any search results for commenting out code in Ant. Is it not a recommended practice? I feel copying all the files to another directory and then removing the lines and then copying it back is overkill. If the compile fails you are left with your code in another directory.

So at the moment I am using the below regex pattern to comment out the code.

 <regexp pattern="(\s*)Log\.d\s*(\(.*\))\s*;"/>
        <substitution expression="\1\/\/AntComment Log\.d\2;"/>

I was wondering if there is a better way i.e. a built in way of handling comments.

Also is there a way trial run ant regex statements to see what it picks up?

Listening to Jean Waghetti i tried a few bits of code with conditional compilation

I just tried a few variations, it seems it needs you to have if(DEBUG) in the same function. So this piece of code will end up having the string literal in the classes.dex file.

Logger.myLog("Sensitive Info" + c); // you call this

//in Logger class - myLog method
static void myLog(String msg){
if(DEBUG){

If you try to have a bit more sophisticated logging, where it needs figure out whether to log but with an and (&&) with DEBUG it ends up adding the string literal in the dex file eg:

public class SomeClass{
  public final boolean log = DEBUG && figure_Log();
  private boolean figure_Log(){
   // some condition based on other settings
 }
  //in the code
  if (log){

To achieve a more sophisticated logging you have to have this:

if(DEBUG && log){ 

before all logging calls, it creates too many unused code warnings and looks ugly for me.

Community
  • 1
  • 1
pt123
  • 2,146
  • 1
  • 32
  • 57
  • Isn't DEBUG a "global variable"? If so, you can use check `if(DEBUG)` in the Log class methods. Even if every class or instance has its own debug enabled or not, I check it only on the "logger" class. If the code of the logging method is empty because it was not compiled, the call to the method will be discarded from the code as well. – Jean Waghetti Aug 08 '13 at 17:34
  • it is a "global variable", the call is discarded but the message shows up in the dex file as a string literals in the dex file of the class that is calling the log class methods. – pt123 Aug 08 '13 at 20:37
  • Are your strings defined outside the method invocation? Like `String debugMessage = "bla"; Log.debug(debugMessage);`? – Jean Waghetti Aug 09 '13 at 14:35
  • no like mentioned in the code above: Logger.myLog("Sensitive Info" + c); – pt123 Aug 09 '13 at 21:46
  • `public final boolean log`= DEBUG && figure_Log()`. `log` should be static, otherwise it will be "generated" for each instance of the class - so it will not be optimized when compiled. You can create code with `if(DEBUG && log)` inside your `Logger` class, and pass the boolean `log` for that instance in the constructor or as a parameter for the logging method. – Jean Waghetti Aug 12 '13 at 13:35
  • The problem was figure_Log() can't be static as it will be passed in whether to log this class or not. Anyway I went with Ant, it allows you to keep the source code simpler. – pt123 Aug 16 '13 at 22:38
  • But static is "class-wise". Not-static is "instance-wise". – Jean Waghetti Aug 19 '13 at 16:56

1 Answers1

0

You can put the code to be removed on a conditional block depending on a final static field.

static final DEBUG = false;

if (DEBUG) {
    System.out.println("debug message");
}

The Java Language Specification has some words about "conditional compilation". It does not enforce it, but the code in the if block can be optimized and not compiled in your class. Oracle javac does this.

You can pass your classes through proguard optimization and it will (almost) certainly strip this part of code if your compiler didn't before.

Jean Waghetti
  • 4,711
  • 1
  • 18
  • 28
  • I have added my comments about my experimentation with conditional compilation in the main post, as there is better room to explain it – pt123 Aug 08 '13 at 12:09