PUBLIC OBJECT

Preprocessing .java with Munge

In the rare situation that you need to preprocess .java files, Munge is a pretty decent tool for getting it done. From Tom Ball's blog,

So a combination preprocessor and string translator, Munge, was created to address [supporting Java 1.1 and Java 2] (source). Since its requirements were that it be small, fast and require no maintenance (it wasn't a product, after all), it purposely has no features that weren't needed by the team. It won't have your favorite cpp or sed feature, but what it did, it did quickly and correctly. It wasn't open-source then, but if you wanted a feature you were handed the source and told to have fun.

We're using Munge in Guice to support both AOP and non-AOP releases. AOP is awesome, but it requires bytecode generation which isn't available on Android yet. To support stripping AOP out, our source files now include preprocessor instructions:

public interface Binder {

  /*if[AOP]*/
  /**
   * Binds a method interceptor to methods matched by class
   * and method matchers.
   */
  void bindInterceptor(Matcher<? super Class<?>> classMatcher,
      Matcher<? super Method> methodMatcher,
      MethodInterceptor... interceptors);
  /*end[AOP]*/

  /**
   * Binds a scope to an annotation.
   */
  void bindScope(Class<? extends Annotation> annotationType,
      Scope scope);

  ...

I patched Munge to be a bit more careful with C-style comments (/*) inside end-of-line comments and strings. This is necessary to handle calls like filter("/*") and serve("/*") in our updated servlet package.

Ours also has an Ant task to munge the entire project in one go:

<target name="no_aop"
        description="Create a copy of the Guice source that doesn't do bytecode generation.">
  <taskdef name="munge" classname="MungeTask" classpath="lib/build/munge.jar"/>
  <mkdir dir="build/no_aop"/>
  <munge todir="build/no_aop">
    <fileset dir="." excludes="build/**/*"/>
    <arg value="-DNO_AOP" />
  </munge>
</target>

If you're preprocessing some .java files and can use these features, help yourself to our custom munge.jar. The jar includes both source and classfiles.