Ajc11CompilerAdapter (javac)

This CompilerAdapter can be used in javac task calls by setting the build.compiler property. This enables users to to easily switch between the Javac and AspectJ compilers. However, the Javac task's pruning of source files prevents the adapter from doing a correct compile in some cases, so use AjcTask where possible.

Sample of compiler adapter

To build using the adapter, put the aspectjtools.jar on the system/ant classpath (e.g., in ${ANT_HOME}/lib) and define the build.compiler property as the fully-qualified name of the class, org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter.

The AspectJ compiler should run for any compile using the Javac task (for options, see the Ant documentation for the Javac task). For example, the call below passes all out-of-date source files in the src/org/aspectj subdirectories to the ajc command along with the destination directory:

		
-- command:

    cp aspectj1.1/lib/aspectjtools.jar ant/lib
    ant/bin/ant -Dbuild.compiler=org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter ...

-- task invocation in the build script:

  <javac srcdir="src" includes="org/aspectj/**/*.java" destdir="dest" />

		

To pass ajc-specific arguments, use a compilerarg entry.

		
-- command

  Ant -Dbuild.compiler=org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter

-- build script

  <property name="ajc" 
              value="org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter"/>

  <javac srcdir="src" includes="org/aspectj/**/*.java" destdir="dest" >
    <compilerarg compiler="${ajc}" line="-argfile src/args.lst"/>
  <javac/>

		

Compiler adapter compilerarg options

The adapter supports any ajc command-line option passed using compilerarg, as well as the following options available only in AjcTask. Find more details on the following options in AjcTask (iajc).

  • -Xmaxmem: set maximum memory for forking (also settable in javac).

  • -Xlistfileargs: list file arguments (also settable in javac).

  • -Xfailonerror: throw BuildException on compiler error (also settable in javac).

  • -Xmessageholderclass: specify fully-qualified name of class to use as the message holder.

  • -Xcopyinjars: copy resources from any input jars to output (default behavior since 1.1.1)

  • -Xsourcerootcopyfilter {filter}: copy resources from source directories to output (minus files specified in filter)

  • -Xtagfile {file}: use file to control incremental compilation

  • -Xsrcdir {dir}: add to list of ajc source roots (all source files will be included).

Special considerations when using Javac and compilerarg:

  • The names above may differ slightly from what you might expect from AjcTask; use these forms when specifying compilerarg.

  • By default the adapter will mimic the Javac task's copying of resource files by specifying "**/CVS/*,**/*.java,**/*.aj" for the sourceroot copy filter. To change this behavior, supply your own value (e.g., "**/*" to copy nothing).

  • Warning - define the system property build.compiler.clean to compile all files, when available. Javac prunes the source file list of "up-to-date" source files based on the timestamps of corresponding .class files, and will not compile if no sources are out of date. This is wrong for ajc which requires all the files for each compile and which may refer indirectly to sources using argument files.

    To work around this, set the global property build.compiler.clean. This tells the compiler adapter to delete all .class files in the destination directory and re-execute the javac task so javac can recalculate the list of source files. e.g.,

    		
      Ant -Dbuild.compiler=org.aspectj.tools.ant.taskdefs.Ajc11CompilerAdapter
          -Dbuild.compiler.clean=anything ...
    
    		

    Caveats to consider when using this global build.compiler.clean property:

    1. If javac believes there are no out-of-date source files, then the adapter is never called and cannot clean up, and the "compile" will appear to complete successfully though it did nothing.

    2. Cleaning will makes stepwise build processes fail if they depend on the results of the prior compilation being in the same directory, since cleaning deletes all .class files.

    3. This clean process only permits one compile process at a time for each destination directory because it tracks recursion by writing a tag file to the destination directory.

    4. When running incrementally, the clean happens only before the initial compile.