0

I would like to be able to have my debug code (verbose logging, etc) compiled out when I make a production release, but compiled in for debugging.

I understand that if I branch on a constant, the compiler will remove the branch, which is what I want. So I have a class:

class Debug {
  public static final boolean ON=true;
}

and my debug code is inside a branch like this:

if (Debug.ON) {
    // Verbose / expensive logging goes here
}

My question is, how do I arrange for Debug.ON to be set to true or false at compile time, short of actually editing the source file?

EDIT: Note that I am not concerned with controlling whether log output appears or not - I am using java.util.Logging and it can take care of that. I am more concerned with compiling out any expensive code that is preparing log messages which will never get output, or taking measurements that are not needed in production mode.

I guess I could have an ant target that makes the source file from a template or something, but it seems like a hack. In C++ I'd be able to define a pre-processor symbol which I could pass in with -D - is there any Java equivalent? Or some other better way?

6
  • 2
    You really want to use logj4 or its brethren. Don't reinvent the wheel. With this, when you build for production you use one logging config file, when you run in development, you use another. Commented Nov 22, 2013 at 3:45
  • 2
    More specifically, use slf4j (or log4j2); you specify your log messages as patterns, and they don't even get evaluated unless you have that particular logging turned on. You're going to add more bugs doing this than you'll offset with time or performance gains. Commented Nov 22, 2013 at 3:48
  • What happens where there is significant computation required to prepare the log message to start with? For example, I have a large buffer full of binary data I want to log in hex format, I need to convert it to hex before even invoking the logging framework. I want to avoid that overhead in a production environment. Commented Nov 22, 2013 at 4:02
  • BTW, should have mentioned at the start, I am currently using java.util.Logging to do the actual logging. I am aware that there are several other frameworks that are probably better, but the main thing I am trying to address is compiling out expensive code in production environments, not controlling whether logging will appear. Commented Nov 22, 2013 at 4:06
  • Read external file or put it into properties. Ugly, but works. Commented Nov 22, 2013 at 4:08

2 Answers 2

1

What you can do is have two Jars or class files.

The one contains the Debug class with ON = true and the other ON = false.

Then when you compile depending on what debug state you want you include the DEBUG on class/jar file or the DEBUG off class/jar file.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! I had thought of doing something like this, but was hoping for a more elegant solution. But it seems Java does not allow it.
0

Michael Wiles' answer is probably the most straightforward way to do exactly what you ask. However, all of the popular logging frameworks let you query whether a logger is configured to actually output anything at a specific logging level.

For java.util.logging you would use isLoggable. While this is not a compile time check, it should be fairly cheap compared to logging something expensive to compute.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.