Java Preprocessor

If you do a google search for java preprocessor you are likely to get a pretty sparse set of results. There are a few projects out there that provide tools to solve this problem but I needed something with the following characteristics:

  1. C preprocessor like syntax with configurable macro prefix
  2. solid Ant integration
    • properties defined in build script visible to preprocessor
    • only process source files newer than target file
  3. open source license

Finally got frustrated enough to just write my own. The end result is a tool called javapp.jar and it is licensed under the GNU GPL.

The core processor logic is implemented in Python and runs under the Java runtime using Jython. I used an excellent lexical analysis module called Plex by Greg Ewing.

Using Python has the distinct advantage of reducing development time (~ 6 hours), but sadly there is a rather significant performance hit. Processing a large project (~ 100 files) for the first time can take upwards of two minutes! Subsequent builds should be much quicker since the ant task will only process source files newer than the destination file.

Downloading

The latest version is javapp-04.zip. The latest source can always be obtained from here.

Getting Started

Extract the zip file and put javapp.jar somewhere Ant can find it. A good permanent spot is $ANT_HOME/lib.

Define and run the task:

<taskdef resource="javapp-defs.xml" />

<property name="os_version" value="4.2" />

<target name="preprocess">
   <javapp destdir="staging" prefix="//#">
      <fileset dir="src" includes="**/*.java" />
      <property name="poo" value="smelly" />
   </javapp>
</target>

Turns this:

public class Poo {
   public static void main(String[] args) {
      //#if defined(poo)
      System.out.println("Poo is ${poo}");
      //#else
      System.out.println("Poo is not defined");
      //#endif

      //#if ${os_version} == 4.1
      System.out.println("OS 4.1");
      //#elif defined(poo) and ${os_version} >= 4.2
      System.out.println("OS 4.2 and above");
      System.out.println("Ooooh; compound expressions");
      //#endif
   }
}

Into this:

public class Poo {
   public static void main(String[] args) {

      System.out.println("Poo is smelly");



      System.out.println("OS 4.2 and above");
      System.out.println("Ooooh; compound expressions");

   }
}

Syntax Reference

See the README file for preprocessor grammar and the Ant task reference.