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, because there are differences in source file
handling between the Javac task and the ajc compiler, not all
Javac task invocations can be turned over to iajc. However, ajc can
compile anything that Javac can, so it should be possible for any
given compile job to restate the Javac task in a way that can be
handled by iajc/ajc.
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/>
The Javac task does special handling of source files that
can interfere with ajc. It removes any files that are not out-of-date
with respect to the corresponding .class files. But ajc requires all
source files, since an aspect may affect a source file that is not out
of date. (For a solution to this, see the build.compiler.clean
property described below.) Conversely, developers sometimes specify a source directory
to javac, and let it search for files for types it cannot find.
AspectJ will not do this kind of searching under the source directory
(since the programmer needs to control which sources are affected).
(Don't confuse the source directory used by Javac with the source root
used by ajc; if you specify a source root to ajc, it will compile
any source file under that source root (without exception or filtering).)
To replace source dir searching in Javac, use an Ant filter to specify
the source files.
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:
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.
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.
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.
When running incrementally, the clean happens only before the initial compile.