views:

50

answers:

4

I'm building a Java application (using Ant with build.xml and build.property files). Now I'd like to be able to create a different "debug" build which prints several diagnostic messages to System.err. This is achieved by something like this (simplified):

private static final boolean DEBUG = false;

public static void debug (String msg) {
    if (DEBUG) {
        System.err.println(msg);
    }
}

Is it possible to influence the value of the DEBUG constant at build time? I guess what I'm looking for is the Java equivalent for C-preprocessor definitions. Ideally I'd have a different build target in the build.xml file, which would set DEBUG to true and create a myapp-debug.jar as output.

A related use of this would be the name of the config file the application is using. This is also specified as a static constant in the source code, but I'd prefer it to be adjustable at build time.

Sorry if this is all obvious to you, I'm not an expert :)

+1  A: 

Java's build with the principle of "build once, run everywhere", so javac doesn't have a preprocessor, and you can't change the variable at compile time in any other way than having one single definition of the variable somewhere, and changing it in the source file before compiling.

If you're only doing this for logging purposes, you should probably look into the java.util.logging package. If you want to have specific controls performed at run-time that can be disabled for production environments, check out information about Java assertions.

Romain
+2  A: 

It is not uncommon to control logging options via a .properties configuration file.

You may read load a properties file, and if the load succeeds (so that the file needs not be present mandatory) use a property which controls logging.

ron
oh sorry i just posted a similar answer while you were answering this question....sorry for redundancy.
smeg4brains
I think you're right: property files are the way to go. I was under the mistaken impression that this would only push the problem one level away, because then I'd have hard-code the name/location of the property file, but then I remembered that I could just look for it in the classpath (including the application JAR, if there is one). Thanks!
Zilk
+1  A: 

i think it would be easier to externalize the variable into a Java Properties textfile. you can then load a defined property from a *.property file or an XML file and have the application logic depend on this property.

something like this in an application.properties file:

application.log.level=DEBUG

which is then loaded by using the load() method of the Properties Class:

Properties props = new Properties();
props.load(new FileInputStream("application.properties"));
String debugLevel=props.getProperty("application.log.level");
boolean debug;
if (debugLevel!=null && debugLevel.equals("DEBUG")) {
    debug=true;
}
smeg4brains
+6  A: 

I'd recommend log4j if this is the only problem you have.

You're likely to have other settings, such as database and queue connections, etc. These should all be externalized into configuration that you can vary depending on environment.

duffymo
..or its intented successor logback: http://logback.qos.ch (+1).
BalusC