Thursday, May 13, 2010

Java pre compiler ... well nearly

Ant
For simple needs, Ant can be used to do substitution in your sources.

We insert into the code a special tag to delimit code that need to be stripped by the Ant script. Let's say we use //@STARTDEBUG@// and //@ENDDEBUG@//.

package academic.howto;

import javax.swing.JFrame;

public class Example {

public static void main(String args[]){
JFrame f = new JFrame();
f.setSize(300,200);
f.setVisible(true);
f.setTitle("HowTo");
//@STARTDEBUG@//
f.setTitle(f.getTitle() + " DEBUG version");
//@ENDDEBUG@//
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

If you execute this code, the JFrame title will have the word "DEBUG" appended to it.

The Ant script to remove the debugging code is :
<project default="buildme">

   <target name="compileprod">
    <copy todir="../out" includeEmptyDirs="false">
    <filterchain>
            <tokenfilter>
            <replacestring from="//@STARTDEBUG@//" to="/*" />
            <replacestring from="//@ENDDEBUG@//" to="*/" />
            </tokenfilter>
    </filterchain>
        <fileset dir=".">
          <include name="**/*.java" />
       </fileset>
    </copy>

    <javac srcdir="../out" />
   </target>

   <target name="compiledebug">
     <javac srcdir="." />
   </target>

  
   <target name="buildme" depends="compileprod" />
</project>



After running this script, the source (in the ..\out directory)
 
package academic.howto;

import javax.swing.JFrame;

public class Example {

  public static void main(String args[]){
    JFrame f = new JFrame();
    f.setSize(300,200);
    f.setVisible(true);
    f.setTitle("HowTo");
    /*
    f.setTitle(f.getTitle() + " DEBUG version");
    */
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
}

Only disadvantage is a few more minutes to compile but that is small trade off for a better runtime code - with less logging etc

http://www.rgagnon.com/javadetails/java-0130.html

this is another method ...have a class with a single static final bool and use if statements ... compiler automatically optimizes. CAUTION:this will work for a single project/ jar. if the variable ( public static final boolean RELEASE = true; ) is in another jar then javac will not optimize as you can replace the jars with the var set to false... for big applications might work if each package has the debug class and care is taken to reference only that.



CODE:

public class Debug {
  public static final boolean RELEASE = true;
  }
In your source, when you need some debugging codes, you included them in
 a if statement like 
if (Debug.RELEASE) {
   System.out.println("The value of i is " + i);
}
During compilation, since Debug.RELEASE is always true, the code will be present. In the production environment, the Debug class looks like this:
public class Debug {
  public static final boolean RELEASE = false;
  }
When compiling in that environment, the debugging code will be absent from the class file since Debug.release is always false.
 
 
 
REFERENCE:

rgagnon.com/..java-0164.html

rgagnon.com/..java-0130.html

Followers