1

In C/C++, I can use as follows

int main()
{

#if defined(DEBUG_MODE)
    // The following code may contain sensitive messages.            
    // But these sensitive messages won't be compiled into the release binary.

    A lot of debugging mode code here, which will bloat the final executable.
    ......
#endif

}

How to do the same thing in Java?

What I want is to reduce the final size of classes and to remove all sensitive debugging messages.

That is, the following Java code is not what I want.

class A
{
    public void f()
    {
       if (DEBUG_MODE)
       {    // The following code may contain sensitive messages.
            // So I want to remove them before release.
            A lot of debugging mode code here, which will bloat the final executable.
            ......
        }
    }
}
xmllmx
  • 39,765
  • 26
  • 162
  • 323
  • Are you asking about comments ? – M Sach Oct 09 '14 at 08:33
  • Is it ? http://stackoverflow.com/questions/1109019/determine-if-a-java-application-is-in-debug-mode-in-eclipse – Suresh Atta Oct 09 '14 at 08:34
  • @sᴜʀᴇsʜᴀᴛᴛᴀ, No. That's not the answer. I have know how to determine current mode is debug/release. What I want is to reduce the size of final classes. – xmllmx Oct 09 '14 at 08:36
  • Define a class, with a `static boolean` variable called `DEBUG`. Then each time you need to add debug code, wrap it into `if(MyClass.DEBUG) { /* debug code here */}`. Set `DEBUG` to `true` or `false`, according to your needs. – BackSlash Oct 09 '14 at 08:36
  • For clarity, is this a question on how to conditionally compile in or out code depending on the "debug" vs "release" build of the code? – Niall Oct 09 '14 at 08:36

4 Answers4

2

One thing you could do, is use assertions. This won't stop the code from reaching your final Jar file, but it will allow you to tell Java to ignore this code completely; assertions are only executed when the -ea flag is used on the Java VM.

public class Test {
    public static main(String... args) {
        assert args.length == 3;
        assert debug();


        process();
    }

    // always runs 
    public static void process() {
        // process
    }

    // only runs with -ea enabled
    public static boolean debug() {
        // debug
    }

}

So, while debugging, ensure the -ea flag is set, and the assertions will be run, while running in production code, do not set the -ea flag and you debug code will be ignored.

The example is nonsensical, but the point is to show how debug code would not affect production code.

PeterK
  • 1,697
  • 10
  • 20
1

This is generally frowned upon in Java for many reasons but if you really need to achieve complete removal your best bet is to use a static final boolean.

public static final boolean Debug = false;

public void test() {
    if ( Debug ) {
        // Debug stuff here - usually will not be included in the .class file if Debug is false.
    }
}

This usually (but it is not guaranteed anywhere as far as I know) completely removes the enclosed code.

The alternative is to use some form of late-binding mechanism to dynamically load the debugging classes while leaving an empty stub for your release code.

OldCurmudgeon
  • 64,482
  • 16
  • 119
  • 213
1

Provided that DEBUG_MODE is a static final boolean in your code, you can use ProGuard in "optimization-only" mode. It will erase all if (false) code from the executable.

Anton Savin
  • 40,838
  • 8
  • 54
  • 90
0

The final executable is compressed and you rarely need to worry about it's size unless you have an embedded device or smart phone. Even with the debug information you might find that with compression and the higher level abstraction it is still smaller than the same C code.

How much difference would an extra MB cost for example? Are we talking about an extra $1000 of hardware needed?

Generally speaking the code is removed at runtime by the JIT based on state at a the time. e.g. when you have the debug flag on or not.

Peter Lawrey
  • 525,659
  • 79
  • 751
  • 1,130
  • How to do if the debugging messages is sensitive, and I want to remove them completely before release? – xmllmx Oct 09 '14 at 08:41
  • 1
    @xmllmx If it's really sensitive I would put in the code a module which is not released. Have a sub-class of the release class which contains the sensitive information and this sub-class is in a separate module. No chance of accidentally doing a debug build which looks like a release build. This could mean that your release class has a few methods which don't do anything (as they are for your purposes to override only) but these will be optimised away at runtime. – Peter Lawrey Oct 09 '14 at 08:44